
/// CryEdit.cpp : Defines the class behaviors for the application.
//

#include "StdAfx.h"

#include <gdiplus.h>
#pragma comment (lib, "Gdiplus.lib")

#include "CryEdit.h"

#include "GameExporter.h"
#include "GameResourcesExporter.h"
#include "Brush\BrushExporter.h"

#include "MainFrm.h"
#include "CryEditDoc.h"
#include "ViewPane.h"
#include "StartupDialog.h"
#include "StringDlg.h"
#include "NumberDlg.h"
#include "SelectObjectDlg.h"
#include "LinkTool.h"
#include "AlignTool.h"
#include "VoxelAligningTool.h"
#include "missionscript.h"
#include "NewLevelDialog.h"
#include "TerrainDialog.h"
#include "SkyDialog.h"
#include "TerrainLighting.h"
#include "SetHeightDlg.h"
#include "VegetationMap.h"
#include "GridSettingsDialog.h"
#include "LayoutConfigDialog.h"
#include "ProcessInfo.h"

#include "ViewManager.h"
#include "ModelViewport.h"
#include "RenderViewport.h"
#include "FileTypeUtils.h"

#include "PluginManager.h"
#include "Objects\Group.h"
#include "Objects\AIPoint.h"
#include "Objects\CloudGroup.h"
#include "Objects\EntityObject.h"

#include "Prefabs\PrefabManager.h"

#include "IEditorImpl.h"
#include "StartupLogoDialog.h"
#include "DisplaySettings.h"
#include "Mailer.h"

#include "ObjectCloneTool.h"

#include "Mission.h"
#include "MissionSelectDialog.h"

#include "CustomFileDialog.h"
#include "TipDlg.h"

#include "EquipPackDialog.h"

#include "Undo\\Undo.h"
#include "Objects\\EntityScript.h"

#include "WeaponProps.h"
#include "MissionProps.h"
#include "ThumbnailGenerator.h"
#include "LayersSelectDialog.h"
#include "ToolsConfigPage.h"

#include "TrackView\TrackViewDialog.h"
#include "GameEngine.h"
#include "LMCompDialog.h"
#include "LightmapCompiler/SceneContext.h"

#include "AI\AIManager.h"
#include "AI\GenerateSpawners.h"

#include "TerrainMoveTool.h"
#include "TerrainModifyTool.h"
#include "ToolBox.h"
#include "Geometry\EdMesh.h"
#include "LightmapGen.h"
#include "Material\MaterialDialog.h"
#include "Material/MaterialManager.h"

#include "LevelInfo.h"
#include "DynamicHelpDialog.h"
#include "PreferencesDialog.h"

#include "MatEditMainDlg.h"

#include "ExportObjects.h"

#include <io.h>
#include <IScriptSystem.h>
#include <IEntitySystem.h>
#include <I3DEngine.h>
#include <ITimer.h>
#include <ISound.h>
#include <IGame.h>
#include <IGameFramework.h>
#include <IItemSystem.h>
#include <ICryAnimation.h>
#include <IPhysics.h>
#include <IGameRulesSystem.h>

#include "ObjectBrowserDialog.h"
#include "TimeOfDayDialog.h"
#include "CryEdit.h"
#include "ShaderCache.h"
#include "GotoPositionDlg.h"
#include "TerrainTextureExport.h"

#include "ConsoleDialog.h"

#include "StringUtils.h"

#include "ScopedVariableSetter.h"

#include "Util\3DConnexionDriver.h"

#include "Console/ConsoleSync.h"
#include "Console/ConsoleHotUpdate.h"
#include "Console/ConsoleOptionsDialog.h"
#include "Console/UploadFilesToConsoleDlg.h"

#include "DimensionsDialog.h"

#include "Terrain/TerrainManager.h"

#include "ProceduralSystem/ProceduralCreation.h"

#include "Util/EditorAutoLevelLoadTest.h"
#include "Util/Ruler.h"
#include "Util/Win32/Win32Utils.h"
#include "Util/IndexedFiles.h"
#include "Util/FileChangeMonitor.h"

#include "SegmentedWorld/GridMapDlg.h"

#include "ResourceCompilerHelper.h"

#include "Asset Browser/AssetMetaDataFileDB.h"
#include "IAssetDisplayDatabase.h"
#include "AVCompressionDialog.h"
#include "Controls/DynamicRibbonBar.h"
#include "Console/ConUploadDependencyFilesDlg.h"

#include "AboutDialog.h"

#include "AVCompression.h"

#include "LevelIndependentFileMan.h"
#include "Dialogs/DashboardDlg.h"
#include "LevelFileDialog.h"
#include "UI/UIManager.h"









/////////////////////////////////////////////////////////////////////////////
// The one and only CCryEditApp object
//////////////////////////////////////////////////////////////////////////
CCryEditApp theApp;

enum
{
	DefaultExportSettings_ExportToPC = true,
	DefaultExportSettings_ExportToConsole = false,
};

#define ERROR_LEN 256

#ifdef USE_WIP_FEATURES_MANAGER
//
// WIP features for main ribbon
//
static void MainRibbonWipFeatureUpdate( int id, const bool* const pbVisible, const bool* const pbEnabled, const bool* const pbSafeMode, const char* pParams )
{
	CMainFrame* pMainFrm = (CMainFrame*)AfxGetMainWnd();
	std::vector<CXTPControl*> controls;

	if( !CDynamicRibbonBar::FindAllControlsOnRibbon( pMainFrm->GetRibbonBar(), id, controls ) )
		return;

	bool bVisible = IS_WIP_FEATURE_VISIBLE( id );
	bool bEnabled = IS_WIP_FEATURE_ENABLED( id );

	for( size_t i = 0, iCount = controls.size(); i < iCount; ++i )
	{
		controls[i]->SetVisible( bVisible );
		controls[i]->SetEnabled( bEnabled );
	}
}
#endif

class CCryDocManager : public CDocManager
{
	CDocTemplate* m_pDefTemplate;
public:
	CCryDocManager() : CDocManager(), m_pDefTemplate(NULL) {}
	CDocTemplate* SetDefaultTemplate(CDocTemplate* pNew)
	{
		CDocTemplate* pOld = m_pDefTemplate;
		m_pDefTemplate = pNew;
		return pOld;
	}
	// Copied from MFC to get rid of the silly ugly unoverridable doc-type pick dialog
	virtual void OnFileNew()
	{
		if (m_templateList.IsEmpty())
		{
			TRACE(traceAppMsg, 0, "Error: no document templates registered with CWinApp.\n");
			AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
			return;
		}

		CDocTemplate* pTemplate = m_pDefTemplate? m_pDefTemplate : (CDocTemplate*)m_templateList.GetHead();
		ASSERT(pTemplate != NULL);
		ASSERT_KINDOF(CDocTemplate, pTemplate);

		pTemplate->OpenDocumentFile(NULL);
		// if returns NULL, the user has already been alerted
	}

};

//////////////////////////////////////////////////////////////////////////////
// CCryEditApp

BEGIN_MESSAGE_MAP(CCryEditApp, CWinApp)
	//{{AFX_MSG_MAP(CCryEditApp)
	ON_COMMAND(ID_TERRAIN, ToolTerrain)
	ON_COMMAND(ID_PROCEDURAL_CREATION, ProceduralCreation)
	ON_COMMAND(IDC_SKY, ToolSky)
	ON_COMMAND(ID_GENERATORS_LIGHTING, ToolLighting)
	ON_COMMAND(ID_TERRAIN_TEXTURE_EXPORT, TerrainTextureExport)
	ON_COMMAND(ID_TERRAIN_REFINETERRAINTEXTURETILES,RefineTerrainTextureTiles)
	ON_COMMAND(ID_GENERATORS_TEXTURE, ToolTexture)
	ON_COMMAND(ID_FILE_EXPORTTOGAME, GenerateSurfaceTexture)
	ON_COMMAND(ID_CONSOLE_SYNC_DATA_TO_THE_CONSOLE,SyncDataToTheConsole)
	ON_COMMAND(ID_CONSOLE_SYNCCAMERA,OnSyncCamera)
	ON_COMMAND(ID_CONSOLE_UPLOAD_FILES,OnUploadFilesToConsole)
	ON_COMMAND(ID_CONSOLE_FORCE_SYNC_LEVEL_FILES,OnForceSyncLevelFiles)
	ON_UPDATE_COMMAND_UI(ID_CONSOLE_SYNCCAMERA,OnSyncCameraUpdateUI)
	ON_COMMAND(ID_CONSOLE_AUTOMATICALLYSYNC_DATA,OnRealtimeAutoSync)
	ON_UPDATE_COMMAND_UI(ID_CONSOLE_AUTOMATICALLYSYNC_DATA,OnRealtimeAutoSyncUpdateUI)
	ON_COMMAND(ID_CONSOLE_OPTIONS, &CCryEditApp::OnConsoleOptions)
	ON_COMMAND(ID_CONSOLE_LOADCURRENTLEVELONTHECONSOLE,OnLoadCurrentLevelOnTheConsole)
	ON_COMMAND(ID_CONSOLE_LAUNCHCURRENTLEVELONTHECONSOLE,OnLaunchCurrentLevelOnTheConsole)
	ON_COMMAND(ID_CONSOLE_EXPORTLEVELANDLAUNCHITONCONSOLE,OnExportLevelAndLaunchCurrentLevelOnTheConsole)
	ON_COMMAND(ID_CONSOLE_UPLOAD_DEPENDENCIES, OnConsoleUploadDependencies )
	ON_COMMAND(ID_CONSOLE_RESET,OnResetConsole)
	ON_COMMAND(ID_FILE_EXPORTTOOBJ, ExportToOBJ)
	ON_COMMAND(ID_EDIT_HOLD, OnEditHold)
	ON_COMMAND(ID_EDIT_FETCH, OnEditFetch)
	ON_COMMAND(ID_GENERATORS_STATICOBJECTS, OnGeneratorsStaticobjects)
	ON_COMMAND(ID_FILE_AUTOBACKUP, OnFileAutoBackup)
	ON_UPDATE_COMMAND_UI(ID_FILE_AUTOBACKUP, OnUpdateFileAutoBackup)
	ON_COMMAND(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE, OnFileExportToGameNoSurfaceTexture)
	ON_COMMAND(ID_VIEW_SWITCHTOGAME, OnViewSwitchToGame)
	ON_COMMAND(ID_EDIT_SELECTALL, OnEditSelectAll)
	ON_COMMAND(ID_EDIT_SELECTNONE, OnEditSelectNone)
	ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
	ON_COMMAND(ID_MOVE_OBJECT, OnMoveObject)
	ON_COMMAND(ID_SELECT_OBJECT, OnSelectObject)
	ON_COMMAND(ID_RENAME_OBJ, OnRenameObj)
	ON_COMMAND(ID_SET_HEIGHT, OnSetHeight)
	ON_COMMAND(ID_SCRIPT_COMPILESCRIPT, OnScriptCompileScript)
	ON_COMMAND(ID_SCRIPT_EDITSCRIPT, OnScriptEditScript)
	ON_COMMAND(ID_EDITMODE_MOVE, OnEditmodeMove)
	ON_COMMAND(ID_EDITMODE_ROTATE, OnEditmodeRotate)
	ON_COMMAND(ID_EDITMODE_SCALE, OnEditmodeScale)
	ON_COMMAND(ID_EDITTOOL_LINK, OnEditToolLink)
	ON_COMMAND(ID_EDITTOOL_UNLINK, OnEditToolUnlink)
	ON_COMMAND(ID_EDITMODE_SELECT, OnEditmodeSelect)
	ON_COMMAND(ID_EDIT_ESCAPE, OnEditEscape)
	ON_COMMAND(ID_OBJECTMODIFY_SETAREA, OnObjectSetArea)
	ON_COMMAND(ID_OBJECTMODIFY_SETHEIGHT, OnObjectSetHeight)
	ON_COMMAND(ID_MODIFY_ALIGNOBJTOSURF, OnAlignToVoxel)
	ON_UPDATE_COMMAND_UI(ID_MODIFY_ALIGNOBJTOSURF, OnUpdateAlignToVoxel)
	ON_UPDATE_COMMAND_UI(ID_EDITTOOL_LINK, OnUpdateEditToolLink)
	ON_UPDATE_COMMAND_UI(ID_EDITTOOL_UNLINK, OnUpdateEditToolUnlink)
	ON_UPDATE_COMMAND_UI(ID_EDITMODE_SELECT, OnUpdateEditmodeSelect)
	ON_UPDATE_COMMAND_UI(ID_EDITMODE_MOVE, OnUpdateEditmodeMove)
	ON_UPDATE_COMMAND_UI(ID_EDITMODE_ROTATE, OnUpdateEditmodeRotate)
	ON_UPDATE_COMMAND_UI(ID_EDITMODE_SCALE, OnUpdateEditmodeScale)
	ON_COMMAND(ID_OBJECTMODIFY_FREEZE, OnObjectmodifyFreeze)
	ON_COMMAND(ID_OBJECTMODIFY_UNFREEZE, OnObjectmodifyUnfreeze)
	ON_COMMAND(ID_EDITMODE_SELECTAREA, OnEditmodeSelectarea)
	ON_UPDATE_COMMAND_UI(ID_EDITMODE_SELECTAREA, OnUpdateEditmodeSelectarea)
	ON_COMMAND(ID_SELECT_AXIS_X, OnSelectAxisX)
	ON_COMMAND(ID_SELECT_AXIS_Y, OnSelectAxisY)
	ON_COMMAND(ID_SELECT_AXIS_Z, OnSelectAxisZ)
	ON_COMMAND(ID_SELECT_AXIS_XY, OnSelectAxisXy)
	ON_UPDATE_COMMAND_UI(ID_SELECT_AXIS_X, OnUpdateSelectAxisX)
	ON_UPDATE_COMMAND_UI(ID_SELECT_AXIS_XY, OnUpdateSelectAxisXy)
	ON_UPDATE_COMMAND_UI(ID_SELECT_AXIS_Y, OnUpdateSelectAxisY)
	ON_UPDATE_COMMAND_UI(ID_SELECT_AXIS_Z, OnUpdateSelectAxisZ)
	ON_COMMAND(ID_UNDO, OnUndo)
	ON_COMMAND(ID_EDIT_CLONE, OnEditClone)
	ON_COMMAND(ID_EXPORT_TERRAIN_GEOM, OnExportTerrainGeom)
	ON_UPDATE_COMMAND_UI(ID_EXPORT_TERRAIN_GEOM, OnUpdateExportTerrainGeom)
	ON_COMMAND(ID_SELECTION_SAVE, OnSelectionSave)
	ON_COMMAND(ID_SELECTION_LOAD, OnSelectionLoad)
	ON_COMMAND(ID_GOTO_SELECTED, OnGotoSelected)
	ON_UPDATE_COMMAND_UI(ID_GOTO_SELECTED, OnUpdateSelected)
	ON_COMMAND(ID_EDIT_PHYS_RESET, OnPhysicsResetState)
	ON_COMMAND(ID_EDIT_PHYS_GET, OnPhysicsGetState)
	ON_COMMAND(ID_EDIT_PHYS_SIMULATE, OnPhysicsSimulateObjects)
	ON_COMMAND(ID_OBJECTMODIFY_ALIGN, OnAlignObject)
	ON_UPDATE_COMMAND_UI(ID_OBJECTMODIFY_ALIGN, OnUpdateAlignObject)
	ON_COMMAND(ID_MODIFY_ALIGNOBJTOSURF, OnAlignToVoxel)
	ON_UPDATE_COMMAND_UI(ID_MODIFY_ALIGNOBJTOSURF, OnUpdateAlignToVoxel)
	ON_COMMAND(ID_OBJECTMODIFY_ALIGNTOGRID, OnAlignToGrid)
	ON_UPDATE_COMMAND_UI(ID_OBJECTMODIFY_ALIGNTOGRID, OnUpdateSelected)
	ON_COMMAND(ID_GROUP_ATTACH, OnGroupAttach)
	ON_UPDATE_COMMAND_UI(ID_GROUP_ATTACH, OnUpdateGroupAttach)
	ON_COMMAND(ID_GROUP_CLOSE, OnGroupClose)
	ON_UPDATE_COMMAND_UI(ID_GROUP_CLOSE, OnUpdateGroupClose)
	ON_COMMAND(ID_GROUP_DETACH, OnGroupDetach)
	ON_UPDATE_COMMAND_UI(ID_GROUP_DETACH, OnUpdateGroupDetach)
	ON_COMMAND(ID_GROUP_MAKE, OnGroupMake)
	ON_UPDATE_COMMAND_UI(ID_GROUP_MAKE, OnUpdateGroupMake)
	ON_COMMAND(ID_GROUP_OPEN, OnGroupOpen)
	ON_UPDATE_COMMAND_UI(ID_GROUP_OPEN, OnUpdateGroupOpen)
	ON_COMMAND(ID_GROUP_UNGROUP, OnGroupUngroup)
	ON_UPDATE_COMMAND_UI(ID_GROUP_UNGROUP, OnUpdateGroupUngroup)
	ON_COMMAND(ID_CLOUDS_CREATE, OnCloudsCreate)
	ON_UPDATE_COMMAND_UI(ID_CLOUDS_CREATE, OnUpdateSelected)
	ON_COMMAND(ID_CLOUDS_DESTROY, OnCloudsDestroy)
	ON_UPDATE_COMMAND_UI(ID_CLOUDS_DESTROY, OnUpdateCloudsDestroy)
	ON_COMMAND(ID_CLOUDS_OPEN, OnCloudsOpen)
	ON_UPDATE_COMMAND_UI(ID_CLOUDS_OPEN, OnUpdateCloudsOpen)
	ON_COMMAND(ID_CLOUDS_CLOSE, OnCloudsClose)
	ON_UPDATE_COMMAND_UI(ID_CLOUDS_CLOSE, OnUpdateCloudsClose)
	ON_COMMAND(ID_SHOW_TIPS, OnShowTips)
	ON_COMMAND(ID_LOCK_SELECTION, OnLockSelection)
	ON_COMMAND(ID_EDIT_LEVELDATA, OnEditLevelData)
	ON_COMMAND(ID_FILE_EDITLOGFILE, OnFileEditLogFile)
	ON_COMMAND(ID_FILE_EDITEDITORINI, OnFileEditEditorini)
	ON_COMMAND(ID_SELECT_AXIS_TERRAIN, OnSelectAxisTerrain)
	ON_COMMAND(ID_SELECT_AXIS_SNAPTOALL, OnSelectAxisSnapToAll)
	ON_UPDATE_COMMAND_UI(ID_SELECT_AXIS_TERRAIN, OnUpdateSelectAxisTerrain)
	ON_UPDATE_COMMAND_UI(ID_SELECT_AXIS_SNAPTOALL, OnUpdateSelectAxisSnapToAll)
	ON_COMMAND(ID_PREFERENCES, OnPreferences)
	ON_BN_CLICKED(ID_RELOAD_TEXTURES, OnReloadTextures)
	ON_COMMAND(ID_RELOAD_SCRIPTS, OnReloadScripts)
	ON_COMMAND(ID_RELOAD_GEOMETRY, OnReloadGeometry)
	ON_COMMAND(ID_RELOAD_TERRAIN, OnReloadTerrain)
	ON_COMMAND(ID_TOGGLE_MULTIPLAYER, OnToggleMultiplayer)
  ON_UPDATE_COMMAND_UI(ID_TOGGLE_MULTIPLAYER, OnToggleMultiplayerUpdate)
	ON_COMMAND(ID_REDO, OnRedo)
	ON_UPDATE_COMMAND_UI(ID_REDO, OnUpdateRedo)
	ON_UPDATE_COMMAND_UI(ID_OBJECTMODIFY_SETAREA, OnUpdateSelected)
	ON_UPDATE_COMMAND_UI(ID_OBJECTMODIFY_SETHEIGHT, OnUpdateSelected)
	ON_UPDATE_COMMAND_UI(ID_OBJECTMODIFY_FREEZE, OnUpdateSelected)
	ON_UPDATE_COMMAND_UI(ID_OBJECTMODIFY_UNFREEZE, OnUpdateFreezed)
	ON_COMMAND(ID_RELOAD_TEXTURES, OnReloadTextures)
	ON_UPDATE_COMMAND_UI(ID_SELECTION_SAVE, OnUpdateSelected)
	ON_UPDATE_COMMAND_UI(ID_UNDO, OnUpdateUndo)
	ON_COMMAND(ID_FILE_NEW, OnCreateLevel)
	ON_COMMAND(ID_FILE_OPEN, OnOpenLevel)
	ON_COMMAND(ID_TERRAIN_COLLISION, OnTerrainCollision)
	ON_UPDATE_COMMAND_UI(ID_TERRAIN_COLLISION, OnTerrainCollisionUpdate)
	ON_COMMAND(ID_SOUND_MUTEALL, OnMuteAll)
	ON_UPDATE_COMMAND_UI(ID_SOUND_MUTEALL, OnUpdateMuteAll)	
	ON_COMMAND(ID_RESOURCES_GENERATECGFTHUMBNAILS, OnGenerateCgfThumbnails)
	ON_COMMAND(ID_AI_GENERATEALL, OnAIGenerateAll)
	ON_COMMAND(ID_AI_GENERATETRIANGULATION, OnAIGenerateTriangulation)
	ON_COMMAND(ID_AI_GENERATEWAYPOINT, OnAIGenerateWaypoint)
	ON_COMMAND(ID_AI_GENERATEFLIGHTNAVIGATION, OnAIGenerateFlightNavigation)
	ON_COMMAND(ID_AI_GENERATE3DVOLUMES, OnAIGenerate3dvolumes)
	ON_COMMAND(ID_AI_VALIDATENAVIGATION, OnAIValidateNavigation)
	ON_COMMAND(ID_AI_GENERATE3DDEBUGVOXELS, OnAIGenerate3DDebugVoxels)
	ON_COMMAND(ID_AI_CLEARALLNAVIGATION, OnAIClearAllNavigation)
	ON_COMMAND(ID_AI_GENERATESPAWNERS, OnAIGenerateSpawners)
	ON_COMMAND(ID_AI_GENERATECOVERSURFACES, OnAIGenerateCoverSurfaces)
	ON_COMMAND(ID_AI_NAVIGATION_SHOW_AREAS, OnAINavigationShowAreas)
	ON_UPDATE_COMMAND_UI(ID_AI_NAVIGATION_SHOW_AREAS, OnAINavigationShowAreasUpdate)
	ON_COMMAND(ID_AI_NAVIGATION_ENABLE_CONTINUOUS_UPDATE, OnAINavigationEnableContinuousUpdate)
	ON_UPDATE_COMMAND_UI(ID_AI_NAVIGATION_ENABLE_CONTINUOUS_UPDATE, OnAINavigationEnableContinuousUpdateUpdate)
	ON_COMMAND(ID_AI_NAVIGATION_NEW_AREA, OnAINavigationNewArea)
	ON_COMMAND(ID_AI_NAVIGATION_TRIGGER_FULL_REBUILD,OnAINavigationFullRebuild)
	ON_COMMAND(ID_AI_NAVIGATION_ADD_SEED,OnAINavigationAddSeed)
	ON_COMMAND(ID_AI_NAVIGATION_VISUALIZE_ACCESSIBILITY, OnVisualizeNavigationAccessibility)
	ON_UPDATE_COMMAND_UI(ID_AI_NAVIGATION_VISUALIZE_ACCESSIBILITY, OnVisualizeNavigationAccessibilityUpdate)
	ON_COMMAND(ID_LAYER_SELECT, OnLayerSelect)
	ON_COMMAND(ID_SWITCH_PHYSICS, OnSwitchPhysics)
	ON_COMMAND(ID_GAME_SYNCPLAYER, OnSyncPlayer)
	ON_UPDATE_COMMAND_UI(ID_SWITCH_PHYSICS, OnSwitchPhysicsUpdate)
	ON_UPDATE_COMMAND_UI(ID_GAME_SYNCPLAYER, OnSyncPlayerUpdate)
	ON_COMMAND(ID_REF_COORDS_SYS, OnRefCoordsSys)
	ON_UPDATE_COMMAND_UI(ID_REF_COORDS_SYS, OnUpdateRefCoordsSys)
	ON_COMMAND(ID_RESOURCES_REDUCEWORKINGSET, OnResourcesReduceworkingset)
	ON_COMMAND(ID_TOOLS_GENERATELIGHTMAPS, OnToolsGeneratelightmaps)
	ON_COMMAND(ID_TOOLS_EQUIPPACKSEDIT, OnToolsEquipPacksEdit)
	ON_COMMAND(ID_TOOLS_UPDATEPROCEDURALVEGETATION, OnToolsUpdateProcVegetation)
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_EDIT_HIDE, OnEditHide)
	ON_UPDATE_COMMAND_UI(ID_EDIT_HIDE, OnUpdateEditHide)
	ON_COMMAND(ID_EDIT_UNHIDEALL, OnEditUnhideall)
	ON_COMMAND(ID_EDIT_FREEZE, OnEditFreeze)
	ON_UPDATE_COMMAND_UI(ID_EDIT_FREEZE, OnUpdateEditFreeze)
	ON_COMMAND(ID_EDIT_UNFREEZEALL, OnEditUnfreezeall)

	ON_COMMAND(ID_SNAP_TO_GRID, OnSnap)
	ON_UPDATE_COMMAND_UI(ID_SNAP_TO_GRID, OnUpdateEditmodeSnap)

	ON_COMMAND(ID_AI_NAVIGATION_DISPLAY_AGENT, OnAINavigationDisplayAgent)
	ON_UPDATE_COMMAND_UI(ID_AI_NAVIGATION_DISPLAY_AGENT, OnAINavigationDisplayAgentUpdate)

	ON_COMMAND(ID_WIREFRAME, OnWireframe)
	ON_UPDATE_COMMAND_UI(ID_WIREFRAME, OnUpdateWireframe)

	ON_COMMAND(ID_POINT_MODE, OnPointmode)
	ON_UPDATE_COMMAND_UI(ID_POINT_MODE, OnUpdatePointmode)

	ON_COMMAND(ID_VIEW_GRIDSETTINGS, OnViewGridsettings)
	ON_COMMAND(ID_VIEW_CONFIGURELAYOUT, OnViewConfigureLayout)

	ON_COMMAND(IDC_SELECTION, OnDummyCommand )
	//////////////////////////////////////////////////////////////////////////
	ON_COMMAND(ID_TAG_LOC1, OnTagLocation1)
	ON_COMMAND(ID_TAG_LOC2, OnTagLocation2)
	ON_COMMAND(ID_TAG_LOC3, OnTagLocation3)
	ON_COMMAND(ID_TAG_LOC4, OnTagLocation4)
	ON_COMMAND(ID_TAG_LOC5, OnTagLocation5)
	ON_COMMAND(ID_TAG_LOC6, OnTagLocation6)
	ON_COMMAND(ID_TAG_LOC7, OnTagLocation7)
	ON_COMMAND(ID_TAG_LOC8, OnTagLocation8)
	ON_COMMAND(ID_TAG_LOC9, OnTagLocation9)
	ON_COMMAND(ID_TAG_LOC10, OnTagLocation10)
	ON_COMMAND(ID_TAG_LOC11, OnTagLocation11)
	ON_COMMAND(ID_TAG_LOC12, OnTagLocation12)
	//////////////////////////////////////////////////////////////////////////
	ON_COMMAND(ID_GOTO_LOC1, OnGotoLocation1)
	ON_COMMAND(ID_GOTO_LOC2, OnGotoLocation2)
	ON_COMMAND(ID_GOTO_LOC3, OnGotoLocation3)
	ON_COMMAND(ID_GOTO_LOC4, OnGotoLocation4)
	ON_COMMAND(ID_GOTO_LOC5, OnGotoLocation5)
	ON_COMMAND(ID_GOTO_LOC6, OnGotoLocation6)
	ON_COMMAND(ID_GOTO_LOC7, OnGotoLocation7)
	ON_COMMAND(ID_GOTO_LOC8, OnGotoLocation8)
	ON_COMMAND(ID_GOTO_LOC9, OnGotoLocation9)
	ON_COMMAND(ID_GOTO_LOC10, OnGotoLocation10)
	ON_COMMAND(ID_GOTO_LOC11, OnGotoLocation11)
	ON_COMMAND(ID_GOTO_LOC12, OnGotoLocation12)
	//////////////////////////////////////////////////////////////////////////

	ON_COMMAND(ID_TOOLS_LOGMEMORYUSAGE, OnToolsLogMemoryUsage)
	ON_COMMAND(ID_TERRAIN_EXPORTBLOCK, OnTerrainExportblock)
	ON_COMMAND(ID_TERRAIN_IMPORTBLOCK, OnTerrainImportblock)
	ON_UPDATE_COMMAND_UI(ID_TERRAIN_EXPORTBLOCK, OnUpdateTerrainExportblock)
	ON_UPDATE_COMMAND_UI(ID_TERRAIN_IMPORTBLOCK, OnUpdateTerrainImportblock)
	ON_COMMAND(ID_TOOLS_CUSTOMIZEKEYBOARD, OnCustomizeKeyboard )
	ON_COMMAND(ID_TOOLS_EXPORT_SHORTCUTS, OnExportShortcuts )
	ON_COMMAND(ID_TOOLS_IMPORT_SHORTCUTS, OnImportShortcuts )
	ON_COMMAND(ID_TOOLS_CONFIGURETOOLS, OnToolsConfiguretools)
	ON_COMMAND(ID_EXPORT_INDOORS, OnExportIndoors)
	ON_COMMAND(ID_VIEW_CYCLE2DVIEWPORT, OnViewCycle2dviewport)
	ON_COMMAND(ID_DISPLAY_GOTOPOSITION, OnDisplayGotoPosition)
	ON_COMMAND(ID_SNAPANGLE, OnSnapangle)
	ON_UPDATE_COMMAND_UI(ID_SNAPANGLE, OnUpdateSnapangle)
	ON_COMMAND(ID_RULER, OnRuler)
	ON_UPDATE_COMMAND_UI(ID_RULER, OnUpdateRuler)
	ON_COMMAND(ID_ROTATESELECTION_XAXIS, OnRotateselectionXaxis)
	ON_COMMAND(ID_ROTATESELECTION_YAXIS, OnRotateselectionYaxis)
	ON_COMMAND(ID_ROTATESELECTION_ZAXIS, OnRotateselectionZaxis)
	ON_COMMAND(ID_ROTATESELECTION_ROTATEANGLE, OnRotateselectionRotateangle)
	ON_COMMAND(ID_CONVERTSELECTION_TOBRUSHES, OnConvertselectionTobrushes)
	ON_COMMAND(ID_CONVERTSELECTION_TOSIMPLEENTITY, OnConvertselectionTosimpleentity)
	ON_UPDATE_COMMAND_UI(ID_CONVERTSELECTION_TOBRUSHES, OnUpdateSelected)
	ON_UPDATE_COMMAND_UI(ID_CONVERTSELECTION_TOSIMPLEENTITY, OnUpdateSelected)
	ON_COMMAND(ID_EDIT_RENAMEOBJECT, OnEditRenameobject)
	ON_COMMAND(ID_CHANGEMOVESPEED_INCREASE, OnChangemovespeedIncrease)
	ON_COMMAND(ID_CHANGEMOVESPEED_DECREASE, OnChangemovespeedDecrease)
	ON_COMMAND(ID_CHANGEMOVESPEED_CHANGESTEP, OnChangemovespeedChangestep)
	ON_COMMAND(ID_MODIFY_AIPOINT_PICKLINK, OnModifyAipointPicklink)
	ON_COMMAND(ID_MODIFY_AIPOINT_PICKIMPASSLINK, OnModifyAipointPickImpasslink)
	ON_COMMAND(ID_GEN_LIGHTMAPS_SELECTED, OnGenLightmapsSelected)
	ON_UPDATE_COMMAND_UI(ID_GEN_LIGHTMAPS_SELECTED, OnUpdateSelected)
	ON_COMMAND(ID_MATERIAL_ASSIGNCURRENT, OnMaterialAssigncurrent)
	ON_COMMAND(ID_MATERIAL_RESETTODEFAULT, OnMaterialResettodefault)
	ON_COMMAND(ID_MATERIAL_GETMATERIAL, OnMaterialGetmaterial)
	ON_COMMAND(ID_TOOLS_UPDATELIGHTMAPS, OnToolsUpdatelightmaps)
	ON_COMMAND(ID_PHYSICS_GETPHYSICSSTATE,OnPhysicsGetState )
	ON_COMMAND(ID_PHYSICS_RESETPHYSICSSTATE,OnPhysicsResetState )
	ON_COMMAND(ID_PHYSICS_SIMULATEOBJECTS,OnPhysicsSimulateObjects )
	ON_UPDATE_COMMAND_UI(ID_PHYSICS_GETPHYSICSSTATE, OnUpdateSelected)
	ON_UPDATE_COMMAND_UI(ID_PHYSICS_RESETPHYSICSSTATE, OnUpdateSelected)
	ON_UPDATE_COMMAND_UI(ID_PHYSICS_SIMULATEOBJECTS, OnUpdateSelected)
	ON_COMMAND(ID_FILE_SAVELEVELRESOURCES, OnFileSavelevelresources)
	ON_COMMAND(ID_VALIDATELEVEL, OnValidatelevel)
	ON_COMMAND(ID_TOOLS_VALIDATEOBJECTPOSITIONS, OnValidateObjectPositions)
	ON_COMMAND(ID_HELP_DYNAMICHELP, OnHelpDynamichelp)
	ON_COMMAND(ID_FILE_CHANGEMOD, OnFileChangemod)
	ON_COMMAND(ID_TERRAIN_RESIZE, OnTerrainResizeterrain)
	ON_COMMAND(ID_TOOLS_PREFERENCES, OnToolsPreferences)
	ON_COMMAND(ID_EDIT_INVERTSELECTION, OnEditInvertselection)
	ON_COMMAND(ID_PREFABS_MAKEFROMSELECTION, OnPrefabsMakeFromSelection)
	ON_COMMAND(ID_PREFABS_REFRESHALL, OnPrefabsRefreshAll)
	ON_COMMAND(ID_PREFABS_ADDSELECTIONTOPREFAB, OnAddSelectionToPrefab)
	ON_COMMAND(ID_TOOLTERRAINMODIFY_SMOOTH, OnToolterrainmodifySmooth)
	ON_COMMAND(ID_TERRAINMODIFY_SMOOTH, OnTerrainmodifySmooth)
	ON_COMMAND(ID_TERRAINMODIFY_RISELOWER, OnToolterrainmodifyRiseLower)
	ON_COMMAND(ID_TERRAINMODIFY_PICKHEIGHT, OnToolterrainmodifyPickHeight)
	ON_COMMAND(ID_TERRAIN_VEGETATION, OnTerrainVegetation)
	ON_COMMAND(ID_TERRAIN_PAINTLAYERS, OnTerrainPaintlayers)

	ON_COMMAND(ID_AVIRECORDER_STARTAVIRECORDING, OnAVCRecorderStart)
	ON_COMMAND(ID_AVIRECORDER_STOPAVIRECORDING, OnAVCRecorderStop)
	ON_COMMAND(ID_AVIRECORDER_PAUSEAVIRECORDING, OnAVCRecorderPause)
	ON_COMMAND(ID_AVIRECORDER_OUTPUTFILENAME, OnAVCOutputFilename)
	ON_COMMAND(ID_AVIRECORDER_SETPARAMETERS, &CCryEditApp::OnAVCSetParameters)

	ON_COMMAND(ID_SWITCHCAMERA_DEFAULTCAMERA, OnSwitchcameraDefaultcamera)
	ON_COMMAND(ID_SWITCHCAMERA_SEQUENCECAMERA, OnSwitchcameraSequencecamera)
	ON_COMMAND(ID_SWITCHCAMERA_SELECTEDCAMERA, OnSwitchcameraSelectedcamera)
	ON_COMMAND(ID_SWITCHCAMERA_NEXT, OnSwitchcameraNext)
	ON_COMMAND(ID_OPEN_MATERIAL_EDITOR, OnOpenMaterialEditor)
	ON_COMMAND(ID_OPEN_CHARACTER_EDITOR, OnOpenCharacterEditor)
	ON_COMMAND(ID_OPEN_DATABASE, OnOpenDataBaseView)
	ON_COMMAND(ID_OPEN_FLOWGRAPH, OnOpenFlowGraphView)
	ON_COMMAND(ID_OPEN_ASSET_BROWSER, OnOpenAssetBrowserView)
	ON_COMMAND(ID_OPEN_TRACKVIEW, OnOpenTrackView)
	ON_COMMAND(ID_GOTO_VIEWPORTSEARCH, OnGotoViewportSearch)
	ON_COMMAND(ID_BRUSH_RESETTRANSFORM, OnBrushResettransform)
	ON_COMMAND(ID_BRUSH_MAKEHOLLOW, OnBrushMakehollow)
	ON_COMMAND(ID_BRUSH_CSGCOMBINE, OnBrushCsgcombine)
	ON_COMMAND(ID_BRUSH_CSGSUBSTRUCT, OnBrushCsgsubstruct)
	ON_COMMAND(ID_BRUSH_CLIPTOOL, OnBrushCliptool)
	ON_COMMAND(ID_BRUSH_UVTOOL, OnBrushUvtool)
	ON_COMMAND(ID_BRUSH_CSGINTERSECT, OnBrushCsgintersect)
	ON_COMMAND(ID_SUBOBJECTMODE_VERTEX, OnSubobjectmodeVertex)
	ON_COMMAND(ID_SUBOBJECTMODE_EDGE, OnSubobjectmodeEdge)
	ON_COMMAND(ID_SUBOBJECTMODE_FACE, OnSubobjectmodeFace)
	ON_COMMAND(ID_SUBOBJECTMODE_POLYGON, OnSubobjectmodePolygon)
	ON_COMMAND(ID_BRUSH_CSGSUBSTRUCT2, OnBrushCsgsubstruct2)
	ON_COMMAND(ID_MATERIAL_PICKTOOL, OnMaterialPicktool)
	ON_COMMAND(ID_DISPLAY_SHOWHELPERS, OnShowHelpers)
	ON_COMMAND(ID_TERRAIN_TIMEOFDAY, OnTimeOfDay)
	ON_COMMAND(ID_TOOLS_CLEARLEVELSHADERCACHE,OnClearLevelShaderList)
	ON_COMMAND(ID_SW_EDIT, OnOpenSWEditor)
	ON_COMMAND(ID_SW_CONVERTTOSW, OnConvertToSegmentedWorld)
#ifndef SEG_WORLD
	ON_UPDATE_COMMAND_UI(ID_SW_EDIT, OnSegWorldDisabled)
	ON_UPDATE_COMMAND_UI(ID_SW_CONVERTTOSW, OnSegWorldDisabled)
#endif
	ON_COMMAND(ID_TOOLS_RESOLVEMISSINGOBJECTS, OnResolveMissingObjects)
	//ON_UPDATE_COMMAND_UI(ID_SHOW_HELPERS, OnUpdateGroupDetach)

	ON_COMMAND(ID_DISPLAY_TOGGLEFULLSCREENMAINWINDOW, OnToggleFullScreenPerspectiveWindow)

	ON_COMMAND_RANGE(ID_GAME_ENABLELOWSPEC,ID_GAME_ENABLEVERYHIGHSPEC, OnChangeGameSpec)
	ON_UPDATE_COMMAND_UI_RANGE(ID_GAME_ENABLELOWSPEC,ID_GAME_ENABLEVERYHIGHSPEC, OnUpdateGameSpec)

	ON_COMMAND_RANGE(ID_GAME_ENABLEX360SPEC,ID_GAME_ENABLEPS3SPEC, OnChangeGameSpec)
	ON_UPDATE_COMMAND_UI_RANGE(ID_GAME_ENABLEX360SPEC,ID_GAME_ENABLEPS3SPEC, OnUpdateGameSpec)

	ON_UPDATE_COMMAND_UI(ID_GAME_ENABLESKETCHMODE, OnUpdateSketchMode)
	ON_COMMAND(ID_GAME_ENABLESKETCHMODE,OnGameEnableSketchMode)

	ON_COMMAND( ID_VIEW_ROLLUPBAR, OnToggleRollupBar)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ROLLUPBAR, OnUpdateRollupBar )
	ON_COMMAND( ID_VIEW_CONSOLEWINDOW, OnToggleConsole)
	ON_UPDATE_COMMAND_UI(ID_VIEW_CONSOLEWINDOW, OnUpdateConsole )

	ON_COMMAND(ID_START_STOP,OnStartStop)
	ON_COMMAND(ID_NEXT_KEY,OnNextKey)
	ON_COMMAND(ID_PREV_KEY,OnPrevKey)
	ON_COMMAND(ID_SELECT_ALL,OnSelectAll)
	ON_COMMAND(ID_SET_KEY,OnKeyAll)
	ON_COMMAND(ID_NEXT_FRAME,OnNextFrame)
	ON_COMMAND(ID_PREV_FRAME,OnPrevFrame)	

	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
	END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCryEditApp construction
CCryEditApp::CCryEditApp()
{
	m_pFileChangeMonitor = NULL;
	m_mutexApplication = NULL;
	m_pAVCompression = NULL; 

	strcpy(m_sPreviewFile,"");

#ifdef _DEBUG
	int tmpDbgFlag;
	tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
	// Clear the upper 16 bits and OR in the desired freqency
	tmpDbgFlag = (tmpDbgFlag & 0x0000FFFF) | (32768 << 16);
	//tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
	_CrtSetDbgFlag(tmpDbgFlag);

	// Check heap every 
	//_CrtSetBreakAlloc(119065);
#endif

	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
	m_pEditor = 0;
	m_bExiting = false;
	m_bPreviewMode = false;
	m_bConsoleMode = false;
	m_bTestMode = false;
	m_bPrecacheShaderList = false;
  m_bStatsShaderList = false;
  m_bMergeShaders = false;
	m_bMatEditMode = false;
	m_pMatEditDlg = 0;
	m_isSaveAutoBackupInProgress = false;
	m_bLevelLoadTestMode = false;

	ZeroStruct(m_tagLocations);
	ZeroStruct(m_tagAngles);

	m_fastRotateAngle = 45;
	m_moveSpeedStep = 0.1f;

	m_pConsoleDialog = 0;

	m_bForceProcessIdle = false;
	m_pFileChangeMonitor = NULL;

	m_AVCWait = NULL;

}

//////////////////////////////////////////////////////////////////////////
CCryEditApp::~CCryEditApp()
{
	if (m_pFileChangeMonitor)
	{
		m_pFileChangeMonitor->StopMonitor();
		SAFE_DELETE( m_pFileChangeMonitor );
	}
}

class CEditCommandLineInfo : public CCommandLineInfo
{
public:
	int paramNum;
	int exportParamNum;
	bool bTest;
	bool bAutoLoadLevel;
	bool bExport;
	bool bMatEditMode;
	bool bExportTexture;
	bool bExportLM;
	bool bPrecacheShaders;
  bool bPrecacheShadersLevels;
	bool bPrecacheShaderList;
	bool bStatsShaders;
	bool bStatsShaderList;
	bool bMergeShaders;
	bool bExportAI;
	bool bConsoleMode;
	bool bDeveloperMode;
	bool bShowSplash;
	CString file;
	CString gameCmdLine;

	CEditCommandLineInfo()
	{
		exportParamNum = -1;
		paramNum = 0;
		bExport = false;
		bMatEditMode = false;
		bPrecacheShaders = false;
    bPrecacheShadersLevels = false;
		bPrecacheShaderList = false;
		bStatsShaders = false;
		bStatsShaderList = false;
		bMergeShaders = false;
		bTest = false;
		bAutoLoadLevel = false;
		bExport = false;
		bExportTexture = false;
		bExportLM = false;
		bExportAI = false;
		bConsoleMode = false;
		bDeveloperMode = false;
		bShowSplash = true;
	}
	virtual void ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL bLast )
	{
		if (bFlag && stricmp(lpszParam,"export")==0)
		{
			exportParamNum = paramNum;
			bExport = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"exportTexture")==0)
		{
			exportParamNum = paramNum;
			bExportTexture = true;
			bExport = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"exportAI")==0)
		{
			exportParamNum = paramNum;
			bExportAI = true;
			bExport = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"exportLM")==0)
		{
			exportParamNum = paramNum;
			bExportLM = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"test")==0)
		{
			bTest = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"auto_level_load")==0)
		{
			bAutoLoadLevel = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"PrecacheShaders")==0)
		{
			bPrecacheShaders = true;
			return;
		}
    else if (bFlag && stricmp(lpszParam,"PrecacheShadersLevels")==0)
    {
      bPrecacheShadersLevels = true;
      return;
    }
		else if (bFlag && stricmp(lpszParam,"PrecacheShaderList")==0)
		{
			bPrecacheShaderList = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"StatsShaders")==0)
		{
			bStatsShaders = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"StatsShaderList")==0)
		{
			bStatsShaderList = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"MergeShaders")==0)
		{
			bMergeShaders = true;
			return;
		}
		else if (bFlag && stricmp(lpszParam,"VTUNE")==0)
		{
			gameCmdLine += " -VTUNE";
			return;
		}
		else if(bFlag && stricmp(lpszParam,"MatEdit")==0)
		{
			bMatEditMode = true;
		}
		else if(bFlag && stricmp(lpszParam,"BatchMode")==0)
		{
			bConsoleMode = true;
		}
		else if(bFlag && stricmp(lpszParam,"devmode")==0)
		{
			bDeveloperMode = true;
		}
		else if(bFlag && stricmp(lpszParam,"nosplash")==0)
		{
			bShowSplash = false;
		}

		if (!bFlag)
		{
			// otherwise it thinks that command parameters included between [] is a filename and tries to load it.
			if (lpszParam[0]=='[')
				return;

			file = lpszParam;
		}
		paramNum++;
		CCommandLineInfo::ParseParam( lpszParam,bFlag,bLast );
	}
};

LRESULT CALLBACK EditorWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{


















	switch(msg)
	{
	case WM_MOVE:
		if(gEnv && gEnv->pSystem)
		{
			CViewport *pViewport = GetIEditor()->GetViewManager()->GetGameViewport();
			if(pViewport)
			{
				RECT rcWindow;
				GetWindowRect(pViewport->m_hWnd,&rcWindow);
				// The main window moves, but not the RenderViewport one, as it's relative to the main window
				// But we are interested by absolute coordinates of the RenderViewport, so use event from main window
				// And coordinates from RenderViewport window ...
				gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_MOVE,rcWindow.left,rcWindow.top);
			}
		}
		return 0;
	default:
		break;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}

/////////////////////////////////////////////////////////////////////////////
// CTheApp::FirstInstance
//		FirstInstance checks for an existing instance of the application. 
//		If one is found, it is activated.
//
//  	This function uses a technique similar to that described in KB 
//  	article Q141752	to locate the previous instance of the application. .
BOOL CCryEditApp::FirstInstance()
{                                       
	CWnd* pwndFirst = CWnd::FindWindow( _T("CryEditorClass"),NULL);
	if (pwndFirst)
	{
		// another instance is already running - activate it
		CWnd* pwndPopup = pwndFirst->GetLastActivePopup();								   
		pwndFirst->SetForegroundWindow();
		if (pwndFirst->IsIconic())
			pwndFirst->ShowWindow(SW_SHOWNORMAL);
		if (pwndFirst != pwndPopup)
			pwndPopup->SetForegroundWindow(); 

		if (m_bPreviewMode)
		{
			// IF in preview mode send this window copy data message to load new preview file.
			COPYDATASTRUCT cd;
			ZeroStruct(cd);
			cd.dwData = 100;
			cd.cbData = strlen(m_sPreviewFile);
			cd.lpData = m_sPreviewFile;
			pwndFirst->SendMessage( WM_COPYDATA,0,(LPARAM)&cd );
		}
		return FALSE;			
	}
	else
	{   
		// this is the first instance
		// Register your unique class name that you wish to use
		WNDCLASS wndcls;
		ZeroStruct( wndcls );
		wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
		wndcls.lpfnWndProc = EditorWndProc;
		wndcls.hInstance = AfxGetInstanceHandle();
		wndcls.hIcon = LoadIcon(IDR_MAINFRAME); // or load a different icon.
		wndcls.hCursor = LoadCursor(IDC_ARROW);
		wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wndcls.lpszMenuName = NULL;

		// Specify your own class name for using FindWindow later
		wndcls.lpszClassName = _T("CryEditorClass");

		// Register the new class and exit if it fails
		if(!AfxRegisterClass(&wndcls))
		{
			TRACE("Class Registration Failed\n");
			return FALSE;
		}
//		bClassRegistered = TRUE;

		return TRUE;
	}
}	

//////////////////////////////////////////////////////////////////////////
CCryEditDoc* CCryEditApp::GetDocument()
{
	return GetIEditor()->GetDocument();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::InitDirectory()
{
	//////////////////////////////////////////////////////////////////////////
	// Initializes Root folder of the game.
	//////////////////////////////////////////////////////////////////////////
	WCHAR szExeFileName[_MAX_PATH];

	GetModuleFileNameW( GetModuleHandle(NULL), szExeFileName, sizeof(szExeFileName));
	PathRemoveFileSpecW(szExeFileName);

	// Remove Bin32/Bin64 folder/
	WCHAR *lpPath = StrStrIW(szExeFileName,L"\\Bin32");
	if (lpPath)
		*lpPath = 0;
	lpPath = StrStrIW(szExeFileName,L"\\Bin64");
	if (lpPath)
		*lpPath = 0;

	SetCurrentDirectoryW( szExeFileName );
}

//////////////////////////////////////////////////////////////////////////
// Needed to work with custom memory manager.
//////////////////////////////////////////////////////////////////////////

CFrameWnd* CCrySingleDocTemplate::CreateNewFrame( CDocument* pDoc, CFrameWnd* pOther )
{
	CFrameWnd* pFrame = (CFrameWnd*)AfxGetMainWnd();
	if (!pFrame || !pFrame->IsKindOf(RUNTIME_CLASS(CMainFrame)))
		return __super::CreateNewFrame(pDoc, pOther);

	ASSERT_KINDOF(CFrameWnd, pFrame);
	ASSERT_VALID(pFrame);

	// connect the original view to the new doc
	CView* pView = pFrame->GetActiveView();
	ASSERT_KINDOF(CLayoutViewPane, pView);
	pDoc->AddView(pView);

	return pFrame;
}

CDocument* CCrySingleDocTemplate::OpenDocumentFile( LPCTSTR lpszPathName, BOOL bMakeVisible /*= TRUE*/ )
{
	return OpenDocumentFile(lpszPathName, TRUE, bMakeVisible);
}

CDocument* CCrySingleDocTemplate::OpenDocumentFile( LPCTSTR lpszPathName, BOOL bAddToMRU, BOOL bMakeVisible )
{
	// Because the whole Editor uses a lot of global variables/singletons to store subsystem data
	// it's strictly based on very single doc, so we have to hack the open process of the other doc type
	assert( AfxGetApp()->m_pDocManager->GetOpenDocumentCount() <= 2 );	// assume there are only two kinds of Doc

	//((CCryEditApp*)AfxGetApp())->m_pDocManager->CloseAllDocuments(TRUE);
	CCryEditDoc* pCurDoc = GetIEditor()->GetDocument();
	if ( pCurDoc && pCurDoc->GetRuntimeClass() != this->m_pDocClass )	// close docs that are not ours
		delete pCurDoc;		// don't close through OnCloseDocument(), that will force frame and view to be destoried

	return __super::OpenDocumentFile(lpszPathName,bAddToMRU,bMakeVisible);
}


/////////////////////////////////////////////////////////////////////////////
// CCryEditApp initialization
BOOL CCryEditApp::InitInstance()
{
	/* 
	// Vlad: memory manager stability test: 6GB (this test) + 2GB (rest of level) = 8GB should work fine on win64
	for(int i=0; i<6; i++)
	{
		byte * p = (byte *)malloc(1024*1024*1024);
		memset(p,0,1024*1024*1024);
	}
	*/

	////////////////////////////////////////////////////////////////////////
	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.
	////////////////////////////////////////////////////////////////////////
	CEditCommandLineInfo cmdInfo;
	bool bReturn;
	
	CProcessInfo::LoadPSApi();

	InitCommonControls();    // initialize common control library
  CWinApp::InitInstance(); // call parent class method


	// Init COM services
	CoInitialize(NULL);
	// Initialize RichEditCtrl.
#if _MFC_VER >= 0x0700 // MFC 7.0
	AfxInitRichEdit2();
#else // MFC 7.0
	AfxInitRichEdit();
#endif // MFC 7.0

#ifdef _AFXDLL
	//Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	//Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	//////////////////////////////////////////////////////////////////////////
	// Initialize GDI+
	//////////////////////////////////////////////////////////////////////////
	Gdiplus::GdiplusStartupInput gdiplusstartupinput;
	Gdiplus::GdiplusStartup (&m_gdiplusToken, &gdiplusstartupinput, NULL);
	//////////////////////////////////////////////////////////////////////////

	// Change the registry key under which our settings are stored.
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization.
	SetRegistryKey(_T("Crytek"));

	LoadStdProfileSettings(8);  // Load standard INI file options (including custom MRU)

	InitDirectory();

	// Check for 32bpp
	if (::GetDeviceCaps(GetDC(NULL), BITSPIXEL) != 32)
		AfxMessageBox("WARNING: Your desktop is not set to 32bpp, this might result in unexpected behavior" \
		"of the editor. Please set your desktop to 32bpp !");

	// replace the default Doc Manager with ours
	SAFE_DELETE(m_pDocManager);
	m_pDocManager = new CCryDocManager;

	// Register the application's document templates. Document templates
	// serve as the connection between documents, frame windows and views
	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CCrySingleDocTemplate(
		IDR_SELECTED_MENU,
		RUNTIME_CLASS(CCryEditDoc),
		RUNTIME_CLASS(CMainFrame),       // main SDI frame window
		RUNTIME_CLASS(CLayoutViewPane));
	AddDocTemplate(pDocTemplate);
	((CCryDocManager*)m_pDocManager)->SetDefaultTemplate(pDocTemplate);

	m_bPreviewMode = false;

	// Parse command line for standard shell commands, DDE, file open
	ParseCommandLine(cmdInfo);

	//
	// When we are in developer mode, just disable the WIP manager, because we want to see even those WIP features, to work on them
	//
#ifdef USE_WIP_FEATURES_MANAGER
	CWipFeatureManager::Instance()->EnableManager( !cmdInfo.bDeveloperMode );
#endif

	//! Copy command line params.
	m_bTestMode = cmdInfo.bTest || cmdInfo.bPrecacheShaders || cmdInfo.bPrecacheShadersLevels || cmdInfo.bMergeShaders || cmdInfo.bPrecacheShaderList || cmdInfo.bStatsShaderList || cmdInfo.bStatsShaders;
	if (													 cmdInfo.bPrecacheShaders || cmdInfo.bPrecacheShadersLevels || cmdInfo.bMergeShaders || cmdInfo.bPrecacheShaderList || cmdInfo.bStatsShaderList || cmdInfo.bStatsShaders)
	{
		m_bPreviewMode = true;
		m_bConsoleMode = true;
	}
	if(cmdInfo.bConsoleMode)
		m_bConsoleMode = true;

	m_bPrecacheShaderList = cmdInfo.bPrecacheShaderList;
  m_bStatsShaderList = cmdInfo.bStatsShaderList;
  m_bStatsShaders = cmdInfo.bStatsShaders;
  m_bPrecacheShaders = cmdInfo.bPrecacheShaders;
  m_bPrecacheShadersLevels = cmdInfo.bPrecacheShadersLevels;
  m_bMergeShaders = cmdInfo.bMergeShaders;
	m_bExportMode = cmdInfo.bExport || cmdInfo.bExportLM;
	if (m_bExportMode)
	{
		m_exportFile = cmdInfo.file;
		m_bTestMode = true;
	}

	// Do we have a passed filename ?
	if (!cmdInfo.m_strFileName.IsEmpty())
	{
		if (IsPreviewableFileType(cmdInfo.m_strFileName.GetBuffer(0)))
		{
			m_bPreviewMode = true;
			strcpy( m_sPreviewFile,cmdInfo.m_strFileName );
		}
	}
	if (!m_bPreviewMode)
	{
		m_mutexApplication = CreateMutex( NULL, TRUE, "CrytekApplication" );
		if (GetLastError() == ERROR_ALREADY_EXISTS)
		{
			if(MessageBox(GetDesktopWindow(), "There is already a Crytek application running\nDo you want to start another one?", "Too many apps", MB_YESNO)!=IDYES)
				return FALSE;
		}
	}
	
	m_bMatEditMode = cmdInfo.bMatEditMode;

	if (!FirstInstance() && !m_bPrecacheShaderList) // Shader precaching may start multiple editor copies.
		return FALSE;

	// Initialize editor interface.
	m_pEditor = new CEditorImpl;

	m_pFileChangeMonitor = new CFileChangeMonitor;
	m_pFileChangeMonitor->Subscribe(this);

	m_pEditor->SetMatEditMode( m_bMatEditMode );

	IInitializeUIInfo *pInitializeUIInfo = 0;
	CStartupLogoDialog logo;
	if (cmdInfo.bShowSplash && !m_bConsoleMode)
	{
		// Do not create logo screen for model viewer.
		logo.Create( CStartupLogoDialog::IDD );

		Version editorVersion = m_pEditor->GetFileVersion();
		if (!(editorVersion[0] == 1 && editorVersion[1] == 1 && editorVersion[2] == 1))
			logo.SetVersion(editorVersion);

		pInitializeUIInfo = &logo;
	}
	else if (m_bConsoleMode)
	{
		m_pConsoleDialog = new CConsoleDialog;
		m_pConsoleDialog->Create(CConsoleDialog::IDD);
		m_pMainWnd = m_pConsoleDialog;
		pInitializeUIInfo = m_pConsoleDialog;
	}

	bool bShaderCacheGen = m_bPrecacheShaderList | m_bPrecacheShaders | m_bPrecacheShadersLevels;

	//////////////////////////////////////////////////////////////////////////
	// Initialize Game System.
	CGameEngine *pGameEngine = new CGameEngine;
	if (!pGameEngine->Init(m_bPreviewMode, m_bTestMode, bShaderCacheGen, GetCommandLine(),pInitializeUIInfo ))
	{
		return FALSE;
	}

	// needs to be called after crysystem has been loaded.
	gSettings.LoadDefaultGamePaths();

	/*
	// make sure the right recent file list is used
	int i = 0;
	CString gamePath = Path::ToUnixPath( Path::MakeFullPath( Path::GetGameFolder() ) );
	while ( m_pRecentFileList->GetSize() > 0 && !(*m_pRecentFileList)[0].IsEmpty() &&
		gamePath.CompareNoCase( Path::ToUnixPath((*m_pRecentFileList)[0]).Left(gamePath.GetLength()) ) != 0 )
	{
		m_pRecentFileList->m_strSectionName.Format( "Recent File List %d", ++i );
		m_pRecentFileList->ReadList();
	}

	*/


	m_pEditor->SetGameEngine( pGameEngine );

	GetISystem()->GetIPak()->MakeDir( "%USER%/Sandbox" );

	// Register File Change Monitor interface
	GetIEditor()->GetSystem()->SetIFileChangeMonitor( this );

	if ( cmdInfo.bAutoLoadLevel ) 
	{
		m_bLevelLoadTestMode = true;
		CEditorAutoLevelLoadTest::Instance();
	}

	if (!m_bPreviewMode && !m_bMatEditMode)
	{
		logo.SetInfo( "Starting Game..." );
		const char * sGameDLL = gEnv->pConsole->GetCVar("sys_dll_game")->GetString();
		GetIEditor()->GetGameEngine()->InitGame(sGameDLL);
	}

	//////////////////////////////////////////////////////////////////////////
	// Apply settings post engine initialization.
	GetIEditor()->GetDisplaySettings()->PostInitApply();
	gSettings.PostInitApply();

#ifdef USE_WIP_FEATURES_MANAGER
	//
	// load the WIP features file
	//
	CWipFeatureManager::Init();
#endif

	//////////////////////////////////////////////////////////////////////////

	//CCustomFileDialog::OpenParams fp;
	//CCustomFileDialog dlg1( fp );
	//dlg1.DoModal();
	//exit(1);


	// create main MDI Frame window
	//CMainFrame* pMainFrame = new CMainFrame;
	//if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
		//return FALSE;
	//m_pMainWnd = pMainFrame;

	if(!GetIEditor()->GetSystem())
		return FALSE;														// system init failed


























































	logo.SetInfo( "Loading Plugins..." );
	// Load the plugins
	{
		bReturn = GetIEditor()->GetPluginManager()->LoadAllPlugins(CString("Editor/Plugins"));

		C3DConnexionDriver *p3DConnexionDriver = new C3DConnexionDriver;
		GetIEditor()->GetPluginManager()->RegisterPlugin( p3DConnexionDriver );
	}

	// Read configuration.
	ReadConfig();

	GetIEditor()->AddUIEnums();	

	if (m_bPreviewMode)
	{
		// Disable all accelerators in preview mode.
		GetIEditor()->EnableAcceleratos( false );

		// Load geometry object.
		if (!cmdInfo.m_strFileName.IsEmpty())
		{
			LoadFile( cmdInfo.m_strFileName );
		}
	}
	else if (m_bExportMode && !m_exportFile.IsEmpty())
	{
		GetIEditor()->SetModifiedFlag(FALSE);
		GetIEditor()->SetModifiedModule(eModifiedNothing);
		CDocument *doc = OpenDocumentFile( m_exportFile );
		if (doc)
		{
			GetIEditor()->SetModifiedFlag(FALSE);
			GetIEditor()->SetModifiedModule(eModifiedNothing);
			if (cmdInfo.bExportAI)
			{
				GetIEditor()->GetGameEngine()->GenerateAiAll();
			}
			ExportLevel( cmdInfo.bExport,cmdInfo.bExportTexture,cmdInfo.bExportLM,true );
			// Terminate process.
			CLogFile::WriteLine("Editor: Terminate Process after export");
		}
		exit(0);
	}
	else if (_stricmp(PathFindExtension(cmdInfo.m_strFileName.GetBuffer(0)), ".cry") == 0)
	{
		CDocument *doc = OpenDocumentFile( cmdInfo.m_strFileName );
		if (doc)
		{
			GetIEditor()->SetModifiedFlag(false);
			GetIEditor()->SetModifiedModule(eModifiedNothing);
		}
	}
	else
	{
		OnFileNew();

		if (CRenderViewport* viewport = static_cast<CRenderViewport*>(GetIEditor()->GetViewManager()->GetGameViewport()))
		{
			viewport->Invalidate();
		}

		CString levelName;

		if (gSettings.bShowDashboardAtStartup)
		{
			CDashboardDlg dashDlg;

			dashDlg.SetRecentFileList(m_pRecentFileList);
			dashDlg.DoModal();
			levelName = dashDlg.GetLevelPath();
		}

		if (levelName == "new")
		{
			if(!CreateLevel())
			{				
				GetIEditor()->GetDocument()->InitEmptyLevel();
			}
		}
		else if (!levelName.IsEmpty())
		{
			// load level				
			CString str;
			str.Format("Loading level %s ...", (LPCSTR)levelName);	
			logo.SetInfo(str);
	
			OpenDocumentFile(levelName);
		}
		else
		{
			logo.SetInfo("Initializing Level...");
			GetIEditor()->GetDocument()->InitEmptyLevel();
		}

		((CMainFrame*)m_pMainWnd)->ShowWindowEx(SW_SHOW);
	}

	if (logo)
	{
		logo.DestroyWindow();
	}

	if (IsInRegularEditorMode())
	{
		CIndexedFiles::StartFileIndexing();
		CAssetMetaDataFileDB::StartLoadAndUpdate();
	}

	if (!m_bMatEditMode && !m_bConsoleMode && !m_bPreviewMode)
	{
		GetIEditor()->UpdateViews();
		if (m_pMainWnd)
			m_pMainWnd->SetFocus();

		// Show tip of the day.
		CTipDlg dlg;
		if (dlg.m_bStartup)
			dlg.DoModal();
	}

	// We don't want the file monitor to be enabled while
	// in console mode...
	if	(!m_bConsoleMode)
	{
		MonitorDirectories();
	}

	if(m_bMatEditMode)
	{
		m_pMatEditDlg = new CMatEditMainDlg(0);
		m_pMainWnd=m_pMatEditDlg;
		//m_pMatEditDlg->SetFocus();

		m_pEditor->InitFinished();
		m_pMatEditDlg->DoModal();
		return FALSE;
	}

	m_pEditor->InitFinished();

	if (m_bPrecacheShaderList)
	{
		GetIEditor()->GetSystem()->GetIConsole()->ExecuteString( "r_PrecacheShaderList" );
		return TRUE;
	}
  else
  if (m_bStatsShaderList)
  {
		GetIEditor()->GetSystem()->GetIConsole()->ExecuteString( "r_StatsShaderList" );
		return TRUE;
  }
  else
	if (m_bStatsShaders)
	{
		GetIEditor()->GetSystem()->GetIConsole()->ExecuteString( "r_StatsShaders" );
		return TRUE;
	}
  else
  if (m_bPrecacheShaders)
  {
		GetIEditor()->GetSystem()->GetIConsole()->ExecuteString( "r_PrecacheShaders" );
		return TRUE;
  }
  else
  if (m_bPrecacheShadersLevels)
  {
		GetIEditor()->GetSystem()->GetIConsole()->ExecuteString( "r_PrecacheShadersLevels" );
		return TRUE;
  }
  else
  if (m_bMergeShaders)
  {
		GetIEditor()->GetSystem()->GetIConsole()->ExecuteString( "r_MergeShaders" );
		return TRUE;
  }

	// Execute special configs.
	gEnv->pConsole->ExecuteString( "exec autoexec.cfg" );
	gEnv->pConsole->ExecuteString( "exec editor.cfg" );
	gEnv->pConsole->ExecuteString( "exec user.cfg" );

	// should be after init game (should be executed even if there is no game)
	if(!GetIEditor()->GetSystem()->GetIGame())
		GetISystem()->ExecuteCommandLine();

	if (IsInRegularEditorMode())
	{
		int startUpMacroIndex = GetIEditor()->GetToolBoxManager()->GetMacroIndex("startup");
		if (startUpMacroIndex >= 0)
		{
			CryLogAlways("Executing the startup macro");
			GetIEditor()->GetToolBoxManager()->ExecuteMacro(startUpMacroIndex);
		}

		m_pAVCompression=new CAVCompression();
	}	

	//
	// register and update the controls that are work in progress
	//
	//REGISTER_WIP_FEATURE( ID_GAME_ENABLEVERYHIGHSPEC, false, false, false, MainRibbonWipFeatureUpdate );
	REGISTER_WIP_FEATURE( ID_GAME_ENABLEPS3SPEC, false, false, false, MainRibbonWipFeatureUpdate );
	REGISTER_WIP_FEATURE( ID_CONSOLE_AUTOMATICALLYSYNC_DATA, false, true, false, MainRibbonWipFeatureUpdate );
	REGISTER_WIP_FEATURE( ID_CONSOLE_SYNC_DATA_TO_THE_CONSOLE, false, true, false, MainRibbonWipFeatureUpdate );

	InitCVars();

	return TRUE;
}

void CCryEditApp::InitCVars()
	{
	REGISTER_INT("ed_DisableShortcutOnFileOpener", 0, 0, "Disable the recent folder access from the file opener dialog." );
}

//////////////////////////////////////////////////////////////////////////
bool CCryEditApp::RegisterListener(IFileChangeListener *pListener, const char* sMonitorItem )
{
	bool bRet = false;

	if ( m_pFileChangeMonitor )
	{
		//char sRealPath[2048];
		char sRelativePath[2048];

		CString strMonitorPath;

		CString masterCD = Path::AddBackslash( CString(GetIEditor()->GetMasterCDFolder()) );

		//gEnv->pCryPak->AdjustFileName(sMonitorItem, sRealPath, 0);
		gEnv->pCryPak->AdjustFileName(sMonitorItem, sRelativePath, ICryPak::FLAGS_NO_FULL_PATH);

		strMonitorPath=Path::ToUnixPath(masterCD / Path::GetGameFolder() / sRelativePath );

		if ( true == m_pFileChangeMonitor->MonitorItem( strMonitorPath) )
		{
			m_vecFileChangeCallbacks.push_back( SFileChangeCallback( pListener,  strMonitorPath) );
			bRet = true;
		}		 
		else
		{
			CryLogAlways( "File Monitor: [%s] not found outside of PAK files. Monitoring disabled for this item", sMonitorItem );
		}
	}
	
	return bRet;
}

bool CCryEditApp::UnregisterListener(IFileChangeListener *pListener)
{
	bool bRet = false;

	// Note that we remove the listener, but we don't currently remove the monitored item
	// from the file monitor. This is fine, but inefficient

	std::vector<SFileChangeCallback>::iterator iter = m_vecFileChangeCallbacks.begin();
	for ( ; iter!=m_vecFileChangeCallbacks.end(); ++iter )
	{
		if ( iter->pListener == pListener)
		{
			m_vecFileChangeCallbacks.erase( iter );
			bRet = true;
			break;
		}
	}

	return bRet;
}

void CCryEditApp::SetNtfsDisableLastAccessUpdate()
{
	DWORD NtfsLastAccess = 0;
	DWORD dwSize = sizeof(NtfsLastAccess);
	HKEY  hKey;
	LONG result;
	result = RegOpenKeyEx( HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\FileSystem",0, KEY_WRITE, &hKey );
	if(result == ERROR_SUCCESS)
	{
		result = RegSetValueEx(hKey, (LPCTSTR) "NtfsDisableLastAccessUpdate", 0, REG_DWORD,(BYTE*)&NtfsLastAccess,dwSize);
		if(result != ERROR_SUCCESS)
			CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "The registry key NtfsDisableLastAccessUpdate in HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\FileSystem failed to be automatically update.");
	}
}

//////////////////////////////////////////////////////////////////////////25
void CCryEditApp::MonitorDirectories()
{
	if(NWin32Utils::IsWindows7() && NWin32Utils::GetNtfsDisabledLastAccessUpdate() != 0 && gSettings.bNtfsLastAccessRegistryUpdateRequest)
	{
		static const char* szErrorMsg = 
			"The registry key NtfsDisableLastAccessUpdate in HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\FileSystem is not set to 0. \n"
			"This can result in file updates not being monitored correctly, thus files not being automatically reloaded. \n"
			"For more information, please refer to http://technet.microsoft.com/en-us/library/cc959914.aspx."
			"Do you want Sandbox to setup the correct value inside your registry?\n"
			"Pressing Cancel will not show this message again";

		int nRes = MessageBox(GetIEditor()->GetEditorMainWnd(),
			szErrorMsg,
			"Warning",
			MB_ICONQUESTION|MB_YESNOCANCEL);

		if(nRes == IDYES)
		{
			SetNtfsDisableLastAccessUpdate();
		}
		if(nRes == IDCANCEL)
		{
			gSettings.bNtfsLastAccessRegistryUpdateRequest = false;
		}

		CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, szErrorMsg);
	}

	CString masterCD = Path::AddBackslash( CString(GetIEditor()->GetMasterCDFolder()) );
/*
	m_pFileChangeMonitor->MonitorItem( masterCD + Path::GetGameFolder() + "\\Shaders\\HWScripts\\" ); // Monitor scripts directory.
	m_pFileChangeMonitor->MonitorItem( masterCD + Path::GetGameFolder() + "\\Textures\\" ); // Monitor textures directory.
	m_pFileChangeMonitor->MonitorItem( masterCD + Path::GetGameFolder() + "\\Objects\\" ); // Monitor objects directory.
	m_pFileChangeMonitor->MonitorItem( masterCD + Path::GetGameFolder() + "\\Levels\\" ); // Monitor levels directory.
	m_pFileChangeMonitor->MonitorItem( masterCD + Path::GetGameFolder() + "\\Animations\\" ); // Monitor animations directory.
*/

	// NOTE: Instead of monitoring each sub-directory we monitor the whole root
	// folder. This is needed since if the sub-directory does not exist when
	// we register it it will never get monitored properly.
	m_pFileChangeMonitor->MonitorItem( masterCD / Path::GetGameFolder() / "" );

	// Add mod paths too
	for (int index = 0; ; index++)
	{
		const char* sModPath = gEnv->pCryPak->GetMod(index);
		if (!sModPath)
			break;
		m_pFileChangeMonitor->MonitorItem( masterCD / sModPath / "" );
	}
}

//////////////////////////////////////////////////////////////////////////
static bool IsFilenameEndsWithDotDaeDotZip(const char *fln)
{
	size_t len = strlen(fln);
	if ( len < 8 )
		return false;

	if ( stricmp(fln + len - 8, ".dae.zip") == 0 )
		return true;
	else
		return false;
}

//////////////////////////////////////////////////////////////////////////
static bool RecompileColladaFile(const char *path)
{
	string pathWithGameFolder = PathUtil::ToUnixPath(PathUtil::AddSlash(PathUtil::GetGameFolder())) + string(path);
	if ( CResourceCompilerHelper().CallResourceCompiler(
		pathWithGameFolder.c_str(), "/refresh", NULL, false, CResourceCompilerHelper::eRcExePath_currentFolder, true, true, L".")
		!= CResourceCompilerHelper::eRcCallResult_success )
		return true;
	else 
		return false;
}

// Called when file monitor message is recieve.
void CCryEditApp::OnFileMonitorChange()
{
	if (m_bExiting)
		return;

	std::set<CString> files;
	
	while (m_pFileChangeMonitor->HaveModifiedFiles())
	{
		SFileChangeInfo change;

		if(m_pFileChangeMonitor->PopNextFileChange(change))
		{
			//TODO: take advantage of the change type in this struct in the future
			if(change.changeType == SFileChangeInfo::eChangeType_Modified)
			{
				files.insert(change.filename);
			}
		}
	}

	if (!files.empty())
	{
		for (std::set<CString>::iterator it = files.begin(); it != files.end(); ++it)
		{
			// Process updated file.
			// Make file relative to MasterCD folder.
			CString filename = Path::FullPathToGamePath(*it);
			CString filenameRelGame = filename;
			filename.Replace( '\\','/' );

			if (!filename.IsEmpty())
			{
				CString ext = filename.Right(filename.GetLength() - filename.ReverseFind('.') - 1);

				// Check for File Monitor callback
				std::vector<SFileChangeCallback>::iterator iter;
				for ( iter=m_vecFileChangeCallbacks.begin(); iter!=m_vecFileChangeCallbacks.end(); ++iter )
				{
					SFileChangeCallback& sCallback = *iter;

					// We compare against length of callback string, so we get directory matches as well as full filenames
					if ( 0 == _strnicmp( filename, sCallback.sItem, sCallback.sItem.GetLength() ) && sCallback.pListener )
					{
						sCallback.pListener->OnFileChange( filename );
					}
				}

				//TODO:  have all these file types encapsulated in some IFileChangeFileTypeHandler to deal with each of them in a more generic way
				bool isCAF = stricmp(ext,"caf") == 0;
				bool isAAC = stricmp(ext,"caa") == 0;
				bool isExportLog = stricmp(ext,"exportlog") == 0;
				bool isRCDone = stricmp(ext,"rcdone") == 0;
				bool isCOLLADA = (stricmp(ext, "dae") == 0 || IsFilenameEndsWithDotDaeDotZip(filename.GetString()));
				bool isMTL = stricmp(ext,"mtl") == 0;

				if (!isCAF && !isAAC && !isCOLLADA && !isExportLog && !isRCDone)
				{
					filenameRelGame = Path::GetRelativePath(filenameRelGame, true);
					filenameRelGame.Replace( '\\','/' );
					GetIEditor()->GetGameEngine()->ReloadResourceFile(filenameRelGame);
				}
				else if (isCOLLADA)
				{
					// Make a corresponding .cgf path.
					CString cgfFileName;
					int nameLength = filename.GetLength();

					cgfFileName=filename;
					if ( stricmp(ext, "dae") == 0 )
					{
						cgfFileName.SetAt(nameLength-3,'c');
						cgfFileName.SetAt(nameLength-2,'g');
						cgfFileName.SetAt(nameLength-1,'f');
					}
					else
					{
						cgfFileName.SetAt(nameLength-7,'c');
						cgfFileName.SetAt(nameLength-6,'g');
						cgfFileName.SetAt(nameLength-5,'f');
						cgfFileName.SetAt(nameLength-4,0);
					}
					IStatObj * pStatObjectToReload = GetIEditor()->Get3DEngine()->FindStatObjectByFilename(cgfFileName.GetBuffer());
					
					// If the corresponding .cgf file exists, recompile the changed COLLADA file.
					if (pStatObjectToReload)
					{
						RecompileColladaFile(filename.GetString());
					}
				}
				else
				{
					ICharacterManager* pICharacterManager = GetISystem()->GetIAnimationSystem();
					stack_string strPath = filename;
					CryStringUtils::UnifyFilePath(strPath);
					int globalID;
					if (isCAF)
						globalID = pICharacterManager->ReloadCAF(strPath.c_str());

				}
				// Set this flag to make sure that the viewport will update at least once,
				// so that the changes will be shown, even if the app does not have focus.
				m_bForceProcessIdle = true;
			}
		}

		if( (gSettings.oHotUpdateSystemSettings.boRealtimeSyncEnabled 
			|| gSettings.oHotUpdateSystemSettings.boAlwaysRealtimeSyncExports)
			&& gSettings.oHotUpdateSystemSettings.IsAnyPlatformEnabled())
		{
			CConsoleHotUpdate::Instance().AddFiles( files );
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::LoadFile( const CString &fileName )
{
	//CEditCommandLineInfo cmdLine;
	//ProcessCommandLine(cmdinfo);

	//bool bBuilding = false;
	//CString file = cmdLine.SpanExcluding()
	if (GetIEditor()->GetViewManager()->GetViewCount() == 0)
		return;
	CViewport *vp = GetIEditor()->GetViewManager()->GetView(0);
	if (vp->IsKindOf( RUNTIME_CLASS(CModelViewport) ))
	{
		((CModelViewport*)vp)->LoadObject( fileName,1 );
	}

	LoadTagLocations();
	if (m_pMainWnd)
		m_pMainWnd->SetWindowText( "CryEngine Sandbox" );

	GetIEditor()->SetModifiedFlag(FALSE);
	GetIEditor()->SetModifiedModule(eModifiedNothing);
}

//////////////////////////////////////////////////////////////////////////
inline void ExtractMenuName(CString& str)
{
	// eliminate &
	int pos = str.Find('&');
	if (pos >= 0)
	{
		str = str.Left(pos) + str.Right(str.GetLength() - pos - 1);
	}
	// cut the string
	for (int i = 0; i < str.GetLength(); i++)
		if (str[i] == 9)
			str = str.Left(i);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::EnableAccelerator( bool bEnable )
{
	/*
	if (bEnable)
	{
		//LoadAccelTable( MAKEINTRESOURCE(IDR_MAINFRAME) );
		m_AccelManager.UpdateWndTable();
		CLogFile::WriteLine( "Enable Accelerators" );
	}
	else
	{
		CMainFrame *mainFrame = (CMainFrame*)m_pMainWnd;
		if (mainFrame->m_hAccelTable)
			DestroyAcceleratorTable( mainFrame->m_hAccelTable );
		mainFrame->m_hAccelTable = NULL;
		mainFrame->LoadAccelTable( MAKEINTRESOURCE(IDR_GAMEACCELERATOR) );
		CLogFile::WriteLine( "Disable Accelerators" );
	}
	*/
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::SaveAutoRemind()
{
	// Added a static variable here to avoid multiple messageboxes to
	// remind the user of saving the file. Many message boxes would appear as this
	// is triggered by a timer even which does not stop when the message box is called.
	// Used a static variable instead of a member variable because this value is not 
	// Needed anywhere else.
	static bool boIsShowingWarning(false);

	// Ingore in game mode, or if no level created, or level not modified
	if (GetIEditor()->IsInGameMode() || GetIEditor()->GetDocument()->GetLevelName() == "" || !GetIEditor()->GetDocument()->IsModified() )
	{
		return;
	}

	if (boIsShowingWarning)
	{
		return;
	}

	boIsShowingWarning=true;
	CString str;
	str.Format( "Auto Reminder: You did not save level for at least %d minute(s)\r\nDo you want to save it now?",gSettings.autoRemindTime );
	if (AfxMessageBox( str,MB_YESNO ) == IDYES)
	{
		// Save now.
		GetIEditor()->SaveDocument();
	}
	boIsShowingWarning=false;
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::SaveAutoBackup()
{
	if(m_isSaveAutoBackupInProgress)
		return;

	if ( !GetIEditor()->IsInGameMode() 
		&& gSettings.autoBackupEnabled
		&& !GetIEditor()->GetGameEngine()->GetLevelPath().IsEmpty()
		&& GetDocument() )
	{
		m_isSaveAutoBackupInProgress = true;
		CWaitCursor wait;

		// Not using GetDocument()->DoSave(filename ,true); because this would add the backup files
		// to the recent files, and we don't want it.
		// For this reason, we are using the Save Level newly created method.
		if (CTerrainManager::GetTerrainManager().GetHeightmap().m_TerrainRGBTexture.WouldSaveSucceed())
		{
			CString filename = Path::Make( GetIEditor()->GetGameEngine()->GetLevelPath(),Path::GetFileName(gSettings.autoBackupFilename),"bak" );
			GetDocument()->SaveLevel(filename);
		}
		m_isSaveAutoBackupInProgress = false;
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::ReadConfig()
{
	//ReadWindowConfig();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::WriteConfig()
{
	if (m_pMainWnd && ::IsWindow(m_pMainWnd->m_hWnd) && m_pMainWnd->IsKindOf(RUNTIME_CLASS(CMainFrame)))
		((CMainFrame*)m_pMainWnd)->SaveConfig();

	IEditor* pEditor = GetIEditor();
	if (pEditor && pEditor->GetDisplaySettings())
	{
		pEditor->GetDisplaySettings()->SaveRegistry();
	}
}

// App command to run the dialog
void CCryEditApp::OnAppAbout()
{
	Version editorVersion = m_pEditor->GetFileVersion();
	CAboutDialog aboutDlg(editorVersion);
	aboutDlg.DoModal();
}


/////////////////////////////////////////////////////////////////////////////
// CCryEditApp message handlers


int CCryEditApp::ExitInstance() 
{
	#ifdef USE_WIP_FEATURES_MANAGER
	//
	// close wip features manager
	//
	CWipFeatureManager::Shutdown();
	#endif

	if (IsInRegularEditorMode() && GetIEditor())
	{
		if (GetIEditor())
		{
			int shutDownMacroIndex = GetIEditor()->GetToolBoxManager()->GetMacroIndex("shutdown");
			if (shutDownMacroIndex >= 0)
			{
				CryLogAlways("Executing the shutdown macro");
				GetIEditor()->GetToolBoxManager()->ExecuteMacro(shutDownMacroIndex);
			}
		}
	}

  if(GetIEditor() && !GetIEditor()->GetGame())
    exit(0); // just exit process in case of "no game" mode

	SAFE_DELETE(m_pAVCompression);
	SAFE_DELETE(m_pConsoleDialog);

	if (GetIEditor())
		GetIEditor()->Notify( eNotify_OnQuit );

	if (IsInRegularEditorMode())
	{
		CAssetMetaDataFileDB::AbortLoadAndUpdate();
		CIndexedFiles::AbortFileIndexing();
		FreeAssetDatabases();
	}

	CBaseObject::DeleteUIPanels();
	CEntityObject::DeleteUIPanels();

	CBaseObject::DeleteUIPanels();

	m_bExiting = true;
	if (m_pFileChangeMonitor)
	{
		m_pFileChangeMonitor->StopMonitor();
		SAFE_DELETE( m_pFileChangeMonitor );
	}

	HEAP_CHECK
	////////////////////////////////////////////////////////////////////////
	// Executed directly before termination of the editor, just write a
	// quick note to the log so that we can later see that the edtor
	// terminated flawless. Also delete temporary files
	////////////////////////////////////////////////////////////////////////
	WriteConfig();

	// Code for saving layout info before termination.
	//CMainFrame*	poMainFrame = (CMainFrame*)AfxGetMainWnd();
	//if (poMainFrame)
	//	poMainFrame->ClosePage( "Flow Graph" );

	//////////////////////////////////////////////////////////////////////////
	// Quick end for editor.
	if (gEnv && gEnv->pSystem)
		gEnv->pSystem->Quit();
	//////////////////////////////////////////////////////////////////////////

	if (m_pEditor)
	{
		m_pEditor->DeleteThis();
		m_pEditor = 0;
	}
	CoUninitialize();

	// save accelerator manager configuration.
	//m_AccelManager.SaveOnExit();

	CProcessInfo::UnloadPSApi();

	Gdiplus::GdiplusShutdown(m_gdiplusToken);

	if (m_mutexApplication)
		CloseHandle(m_mutexApplication);

	return CWinApp::ExitInstance();
}
 
BOOL CCryEditApp::OnIdle(LONG lCount) 
{
	//HEAP_CHECK
	if (!m_pMainWnd)
		return 0;

	////////////////////////////////////////////////////////////////////////
	// Call the update function of the engine
	////////////////////////////////////////////////////////////////////////
	if (m_bTestMode)
	{
		// Terminate process.
		CLogFile::WriteLine("Editor: Terminate Process");
		exit(0);
	}

	CWnd *pWndForeground = CWnd::GetForegroundWindow();
	CWnd *pForegroundOwner = NULL;

	bool bIsAppWindow = (pWndForeground == m_pMainWnd);
	if (pWndForeground)
	{
		DWORD wndProcId = 0;
		DWORD wndThreadId = GetWindowThreadProcessId( pWndForeground->GetSafeHwnd(),&wndProcId );
		if (GetCurrentProcessId() == wndProcId)
		{
			bIsAppWindow = true;
		}
	}
	bool bActive = false;
	int res = 0;
	if (bIsAppWindow || m_bForceProcessIdle)
	{
		res = 1;
		bActive = true;
	}
	m_bForceProcessIdle = false;

	// focus changed
	if (m_bPrevActive != bActive)
		GetIEditor()->GetSystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_CHANGE_FOCUS,bActive,0);

	m_bPrevActive = bActive;

	if (bActive)
	{
		if (GetIEditor()->IsInGameMode())
		{
			// Update Game
			GetIEditor()->GetGameEngine()->Update();
		}
		else
		{
			if(!m_bMatEditMode)
			{
				// Start profiling frame.
				GetIEditor()->GetSystem()->GetIProfileSystem()->StartFrame();

			// Update UI.
			CDynamicHelpDialog::OnIdle();

				bool bUpdateMovieSystemFirst = GetIEditor()->GetSystem()->IsEarlyMovieSystemUpdateOn();
				if (bUpdateMovieSystemFirst)
				{
					if (m_pEditor)
						m_pEditor->Update();
				}

				GetIEditor()->GetGameEngine()->Update();

				if (!bUpdateMovieSystemFirst)
				{
					if (m_pEditor)
						m_pEditor->Update();
				}


				// syncronize all animations so ensure that their compuation have finished	
				GetIEditor()->GetSystem()->GetIAnimationSystem()->SyncAllAnimations();
			
				GetIEditor()->Notify( eNotify_OnIdleUpdate );

				GetIEditor()->GetSystem()->GetIProfileSystem()->EndFrame();
			}
		}
		OnAVCUpdateScreen();


	}
  else if (GetIEditor()->GetSystem() && GetIEditor()->GetSystem()->GetILog())
    GetIEditor()->GetSystem()->GetILog()->Update(); // print messages from other threads

	CWinApp::OnIdle(lCount);

	return res;
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::ExportLevel( bool bExportToGame,bool bExportTexture,bool bExportLM,bool bAutoExport )
{
	if (bExportTexture)
	{
		CGameExporter gameExporter;
		gameExporter.SetAutoExportMode( bAutoExport );
		gameExporter.Export(true,false);
	}
	else if (bExportToGame)
	{
		CGameExporter gameExporter;
		gameExporter.SetAutoExportMode( bAutoExport );
		gameExporter.Export(false,false);
		// After export.
//		OnAiGenerateTriangulation();
//		OnAiGenerate3dvolumes();	
	}

	if (bExportLM)
	{
/*
		CLMCompDialog cDialog(m_pEditor->GetSystem());
		cDialog.Create( CLMCompDialog::IDD );
		cDialog.ShowWindow( SW_SHOW );
		cDialog.RecompileAll();
		cDialog.DestroyWindow();
*/
		//Get scene context singleton
		CSceneContext& sceneCtx = CSceneContext::GetInstance();
		sceneCtx.m_bDistributedMap = true;
		SSharedLMEditorData sSharedData;
		CLightmapGen cLightmapGen(&sSharedData);
		cLightmapGen.GenerateAll( GetIEditor(),NULL );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditFetch()
{
	////////////////////////////////////////////////////////////////////////
	// Get the latest state back
	////////////////////////////////////////////////////////////////////////
	GetIEditor()->GetDocument()->FetchFromFile( HOLD_FETCH_FILE );
}

void CCryEditApp::OnEditHold()
{
	////////////////////////////////////////////////////////////////////////
	// Save the current state
	////////////////////////////////////////////////////////////////////////
	GetIEditor()->GetDocument()->HoldToFile( HOLD_FETCH_FILE );
}

void CCryEditApp::ExportToOBJ()
{
	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if(!sel)
		return;

	if(sel->GetCount() == 0)
	{
		AfxMessageBox("No object selected!");
		return;
	}

	if(false == CExportObjects::CheckIsExportable(sel))
		return;

	char szFilters[] = "Object files (*.obj)|*.obj|All files (*.*)|*.*||";
	CAutoDirectoryRestoreFileDialog dlg(FALSE, "obj", "*.obj", OFN_OVERWRITEPROMPT|OFN_NOCHANGEDIR, szFilters);
	
	// Obtain the position of the terrain marker
	if (dlg.DoModal() == IDOK) 
	{
		CExportObjects exp;
		exp.Export(dlg.GetPathName().GetBuffer(1));
	}
}

void CCryEditApp::UserExportToGame(bool bExportTexture, bool bReloadTerrain, bool bShowText)
{
#ifdef IS_LIMITED_SANDBOX
	AfxMessageBox("This feature is disabled.", MB_ICONWARNING|MB_OK);
	return;
#endif

	if (!GetIEditor()->GetGameEngine()->IsLevelLoaded())
	{
		AfxMessageBox("Please load a level before attempting to export.", MB_ICONWARNING|MB_OK);
	}
	else
	{
		CAIManager *pAIMgr = GetIEditor()->GetAI();
		if(pAIMgr && !pAIMgr->IsNavigationFullyGenerated())
		{
			int msgBoxResult = CryMessageBox("The processing of the navigation data is still not completed."
				" If you export now the navigation data will probably be corrupted."
				" Do you want to proceed anyway with the export operation?",
				"Navigation System Warning",MB_YESNO|MB_ICONQUESTION);
			if(msgBoxResult != IDYES)
			{
				return;
			}
		}

		// Record errors and display a dialog with them at the end.
		CErrorsRecorder errRecorder;

		// Change the cursor to show that we're busy.
		CWaitCursor wait;

		// Temporarily disable auto backup.
		CScopedVariableSetter<bool> autoBackupEnabledChange(gSettings.autoBackupEnabled, false);
		CScopedVariableSetter<int> autoRemindTimeChange(gSettings.autoRemindTime, 0);

		CDimensionsDialog	oDimensionDialog;
		if (bExportTexture)
		{
			// 4096x4096 is default
			oDimensionDialog.SetDimensions(4096);

			if(bShowText)
				oDimensionDialog.SetText("You need to regenerate surface texture:");

			// Query the size of the preview
			if (oDimensionDialog.DoModal() == IDCANCEL)
				return;
		}

		if ( GetIEditor()->GetConsoleSync()->IsRealTimeSyncing() )
			GetIEditor()->GetConsoleSync()->LaunchGameLevelOnConsole();

		CGameExporter gameExporter;
		CString result = gameExporter.Export(bExportTexture, bReloadTerrain, true, eLittleEndian, ".", bShowText, &oDimensionDialog, true);		
	}
}

void CCryEditApp::ExportToGame(bool bShowText)
{
	if (!GetIEditor()->GetGameEngine()->IsLevelLoaded())
	{
		CErrorsRecorder errRecorder;

		// If level not loaded first fast export terrain.
		//GetDocument()->ExportToGame(false);
		CGameExporter gameExporter;
		gameExporter.Export(false,true);
	}
	else
	{
		UserExportToGame( true, true, bShowText );
	}
}


void CCryEditApp::GenerateSurfaceTexture()
{
	ExportToGame();
}

void CCryEditApp::SyncDataToTheConsole()
{
	GetIEditor()->GetConsoleSync()->FullSync();
	GetDocument()->SetModifiedModules(eModifiedNothing);
}

void CCryEditApp::OnSyncCamera()
{
	gSettings.oHotUpdateSystemSettings.boSyncCamera=!gSettings.oHotUpdateSystemSettings.boSyncCamera;

	// To make sure it will be update right-away without any need for changing the position any further.
	if (gSettings.oHotUpdateSystemSettings.boSyncCamera)
	{
		GetIEditor()->GetConsoleSync()->SyncCamera(CConsoleSynchronization::eStartSync);
	}
	else
	{
		GetIEditor()->GetConsoleSync()->SyncCamera(CConsoleSynchronization::eEndSync);
	}
}

void CCryEditApp::OnSyncCameraUpdateUI(CCmdUI *pCmdUI)
{
	if (gSettings.oHotUpdateSystemSettings.boSyncCamera)
	{
		pCmdUI->SetCheck(1);
	}
	else
	{
		pCmdUI->SetCheck(0);
	}
}

void CCryEditApp::OnRealtimeAutoSync()
{
	gSettings.oHotUpdateSystemSettings.boRealtimeSyncEnabled=!gSettings.oHotUpdateSystemSettings.boRealtimeSyncEnabled;

	// We MUST notify that the options changed to make sure that all entities will
	// have the same IDs.
	GetIEditor()->GetConsoleSync()->NotifyOptionsChanged();

	if (gSettings.oHotUpdateSystemSettings.boRealtimeSyncEnabled)
	{
		GetIEditor()->GetConsoleSync()->SyncTimeOfDay();
	}
}

void CCryEditApp::OnRealtimeAutoSyncUpdateUI(CCmdUI *pCmdUI)
{
	pCmdUI->Enable( IS_WIP_FEATURE_ENABLED( ID_CONSOLE_AUTOMATICALLYSYNC_DATA ) );

	if (gSettings.oHotUpdateSystemSettings.boRealtimeSyncEnabled)
	{
		pCmdUI->SetCheck(1);
	}
	else
	{
		pCmdUI->SetCheck(0);
	}
}

void CCryEditApp::OnConsoleOptions()
{
#ifdef IS_LIMITED_SANDBOX
	AfxMessageBox("This feature is disabled.", MB_ICONWARNING|MB_OK);	
	return;
#endif

	CConsoleOptionsDialog	oConsoleOptionsDialog;
	if (oConsoleOptionsDialog.DoModal() == IDOK)
	{
		// In case we need to update some options, this is the place.
	}	
}

void CCryEditApp::OnLoadCurrentLevelOnTheConsole()
{
	GetIEditor()->GetConsoleSync()->LoadLevelOnConsole();
}

void CCryEditApp::OnResetConsole()
{
	if( IDNO == AfxMessageBox( "Are you sure you want to reset the console(s) ?", MB_ICONWARNING|MB_YESNO ) )
		return;

	CConsoleHotUpdate::Instance().ResetConsoles();
}

void CCryEditApp::OnLaunchCurrentLevelOnTheConsole()
{
	GetIEditor()->GetConsoleSync()->LaunchGameLevelOnConsole();
}

void CCryEditApp::OnToggleFullScreenPerspectiveWindow()
{
	CWnd* wnd = ((CMainFrame*)m_pMainWnd)->FindPage("Perspective");
	if (!wnd)
		return;

	CRenderViewport* viewport = (CRenderViewport*) wnd;

	viewport->ToggleFullscreen();
}

void CCryEditApp::OnExportLevelAndLaunchCurrentLevelOnTheConsole()
{
#ifdef IS_LIMITED_SANDBOX
	AfxMessageBox("This feature is disabled.", MB_ICONWARNING|MB_OK);	
	return;
#endif

	CConsoleHotUpdate::Instance().ExportAndLaunch();
}

void CCryEditApp::OnConsoleUploadDependencies()
{
	static CConUploadDependencyFilesDlg dlg;

	if( !dlg.GetSafeHwnd() )
	{
		dlg.Create( CConUploadDependencyFilesDlg::IDD, AfxGetMainWnd() );
	}

	// return if we cannot start the upload
	if( !dlg.StartUpload() )
	{
		return;
	}

	dlg.ShowWindow( SW_SHOW );
}

void CCryEditApp::OnFileAutoBackup()
{
	gSettings.autoBackupEnabled = !gSettings.autoBackupEnabled;
}

void CCryEditApp::OnUpdateFileAutoBackup(CCmdUI* pCmdUI)
{
	pCmdUI->SetCheck(gSettings.autoBackupEnabled);
}

void CCryEditApp::OnFileExportToGameNoSurfaceTexture() 
{
	UserExportToGame(false, false, false);
}

void CCryEditApp::ToolTerrain()
{
	((CMainFrame*)m_pMainWnd)->OpenPage( "Terrain Editor" );
}

void CCryEditApp::ProceduralCreation()
{
	GetIEditor()->OpenView(PROC_WINDOW_NAME);
}

void CCryEditApp::ToolSky()
{
	////////////////////////////////////////////////////////////////////////
	// Show the sky dialog
	////////////////////////////////////////////////////////////////////////

	CSkyDialog cDialog;

	cDialog.DoModal();
	if (GetIEditor()->GetDocument()->IsModified())
	{
		GetIEditor()->GetGameEngine()->ReloadEnvironment();
	}
}

void CCryEditApp::ToolLighting()
{
	////////////////////////////////////////////////////////////////////////
	// Show the terrain lighting dialog
	////////////////////////////////////////////////////////////////////////

	// Disable all tools. (Possible layer painter tool).
	GetIEditor()->SetEditTool(0);

	GetIEditor()->OpenView(LIGHTING_TOOL_WINDOW_NAME);
}

void CCryEditApp::TerrainTextureExport()
{
	GetIEditor()->SetEditTool(0);

	CTerrainTextureExport cDialog;
	cDialog.DoModal();
}

void CCryEditApp::RefineTerrainTextureTiles()
{
	if(AfxMessageBox("Refine TerrainTexture?\r\n"
		"(all terrain texture tiles become split in 4 parts so a tile with 2048x2048\r\n"
		"no longer limits the resolution) You need to save afterwards!",MB_YESNO)==IDYES)
		if(!GetIEditor()->GetHeightmap()->m_TerrainRGBTexture.RefineTiles())
			AfxMessageBox("TerrainTexture refine failed (make sure current data is saved)",MB_OK|MB_ICONHAND);
		else
			AfxMessageBox("Successfully refined TerrainTexture - Save is now required!",MB_OK);

}

void CCryEditApp::ToolTexture()
{
	GetIEditor()->SetEditTool(0);		// close e.g. "layer painting tool" , to force reinit of the tool

	////////////////////////////////////////////////////////////////////////
	// Show the terrain texture dialog
	////////////////////////////////////////////////////////////////////////

	GetIEditor()->OpenView( "Terrain Texture Layers" );
}

void CCryEditApp::OnGeneratorsStaticobjects() 
{
	////////////////////////////////////////////////////////////////////////
	// Show the static objects dialog
	////////////////////////////////////////////////////////////////////////
/*
	CStaticObjects cDialog;

	cDialog.DoModal();

	BeginWaitCursor();
	GetIEditor()->UpdateViews( eUpdateStatObj );
	GetIEditor()->GetDocument()->GetStatObjMap()->PlaceObjectsOnTerrain();
	EndWaitCursor();
	*/
}

void CCryEditApp::OnFileCreateopenlevel() 
{
	////////////////////////////////////////////////////////////////////////
	// Create a new level or open an existing one
	////////////////////////////////////////////////////////////////////////

	CStartupDialog cDialog;

	cDialog.DoModal();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditSelectAll() 
{
	////////////////////////////////////////////////////////////////////////
	// Select all map objects
	////////////////////////////////////////////////////////////////////////
	AABB box( Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX ),Vec3(FLT_MAX,FLT_MAX,FLT_MAX) );
	GetIEditor()->GetObjectManager()->SelectObjects( box );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditSelectNone() 
{
	CUndo undo( "Unselect All" );
	////////////////////////////////////////////////////////////////////////
	// Remove the selection from all map objects
	////////////////////////////////////////////////////////////////////////
	GetIEditor()->ClearSelection();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditInvertselection()
{
	GetIEditor()->GetObjectManager()->InvertSelection();
}

void CCryEditApp::OnEditDelete() 
{
	// If Edit tool active cannot delete object.
	if (GetIEditor()->GetEditTool())
	{
		if (GetIEditor()->GetEditTool()->OnKeyDown( GetIEditor()->GetViewManager()->GetView(0),VK_DELETE,0,0 ))
			return;
	}

	if (GetIEditor()->GetObjectManager()->GetSelection()->IsEmpty())
	{
		AfxMessageBox("You have to select objects before you can delete them !",MB_OK|MB_APPLMODAL );
		return;
	}

	CString strAsk = "Delete selected objects?";
	int flowGraphCount = GetIEditor()->GetObjectManager()->GetSelection()->GetFlowGraphCount();
	int flowGraphReferenceCount = GetIEditor()->GetObjectManager()->GetSelection()->GetFlowGraphReferenceCount();
	if (flowGraphCount > 0)
		strAsk.AppendFormat("\n%d flow graph(s) will be deleted!!", flowGraphCount);
	if (flowGraphReferenceCount > 0)
		strAsk.AppendFormat("\nIn addition, %d reference(s) by flow graphs will be lost!", flowGraphReferenceCount);

	int iResult = MessageBox( AfxGetMainWnd()->GetSafeHwnd(),strAsk.GetBuffer(0), "Delete", MB_ICONQUESTION|MB_YESNO|MB_APPLMODAL );
	if (iResult == IDYES)
	{
		GetIEditor()->BeginUndo();
		GetIEditor()->GetObjectManager()->DeleteSelection();
		GetIEditor()->AcceptUndo( "Delete Selection" );
		GetIEditor()->SetModifiedFlag();
		GetIEditor()->SetModifiedModule(eModifiedBrushes);
	}
}

void CCryEditApp::OnEditClone() 
{
	if (GetIEditor()->GetObjectManager()->GetSelection()->IsEmpty())
	{
		AfxMessageBox("You have to select objects before you can clone them !");
		return;
	}

	CEditTool *tool = GetIEditor()->GetEditTool();
	if (tool && tool->IsKindOf( RUNTIME_CLASS(CObjectCloneTool)))
	{
		((CObjectCloneTool*)tool)->Accept();
	}

	GetIEditor()->SetEditTool( new CObjectCloneTool );
	GetIEditor()->SetModifiedFlag();
	GetIEditor()->SetModifiedModule(eModifiedBrushes);
}


void CCryEditApp::OnEditEscape() 
{
	CEditTool* pEditTool= GetIEditor()->GetEditTool();
	// Abort current operation.
	if (pEditTool)
	{
		// If Edit tool active cannot delete object.
		CViewport* vp = GetIEditor()->GetActiveView();
		if (GetIEditor()->GetEditTool()->OnKeyDown( vp,VK_ESCAPE,0,0 ))
			return;

		if (GetIEditor()->GetEditMode() == eEditModeSelectArea)
			GetIEditor()->SetEditMode(eEditModeSelect);

		// Disable current tool.
		GetIEditor()->SetEditTool(0);
	}
	else
	{
		// Clear selection on escape.
		GetIEditor()->ClearSelection();
	}

	// Reset Control vibration
	// NB could put this somehwere : g_pInputCVars->i_forcefeedback = 0
	IInput* pIInput = GetISystem()->GetIInput(); // Cache IInput pointer.
	if( pIInput && pIInput->HasInputDeviceOfType(eIDT_Gamepad) )
	{
		pIInput->ForceFeedbackEvent( SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.0f, 0.0f, 0.0f) );
	}
}

void CCryEditApp::OnMoveObject()
{
	////////////////////////////////////////////////////////////////////////
	// Move the selected object to the marker position
	////////////////////////////////////////////////////////////////////////
}

void CCryEditApp::OnSelectObject()
{
	////////////////////////////////////////////////////////////////////////
	// Bring up the select object dialog
	////////////////////////////////////////////////////////////////////////

	GetIEditor()->OpenView( "Select Objects" );
}

void CCryEditApp::OnRenameObj()
{
}

void CCryEditApp::OnSetHeight() 
{
}

void CCryEditApp::OnScriptCompileScript() 
{
	////////////////////////////////////////////////////////////////////////
	// Use the Lua compiler to compile a script
	////////////////////////////////////////////////////////////////////////
	CErrorsRecorder errRecorder;

	std::vector<CString> files;
	if (CFileUtil::SelectMultipleFiles( EFILE_TYPE_ANY,files,"Lua Files (*.lua)|*.lua||","Scripts" ))
	{
		//////////////////////////////////////////////////////////////////////////
		// Lock resources.
		// Speed ups loading a lot.
		ISystem *pSystem = GetIEditor()->GetSystem();
		pSystem->GetI3DEngine()->LockCGFResources();
		pSystem->GetIAnimationSystem()->LockResources();
		gEnv->pSoundSystem->LockResources();
		//////////////////////////////////////////////////////////////////////////
		for (int i = 0; i < files.size(); i++)
		{
			if (!CFileUtil::CompileLuaFile( files[i] ))
				return;

			// No errors
			// Reload this lua file.
			GetIEditor()->GetSystem()->GetIScriptSystem()->ReloadScript( files[i],false );
		}
		//////////////////////////////////////////////////////////////////////////
		// Unlock resources.
		// Some uneeded resources that were locked before may get released here.
		gEnv->pSoundSystem->UnlockResources();
		pSystem->GetIAnimationSystem()->UnlockResources();
		pSystem->GetI3DEngine()->UnlockCGFResources();
		//////////////////////////////////////////////////////////////////////////
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnScriptEditScript() 
{
	// Let the user choose a LUA script file to edit
	CString file;
	if (CFileUtil::SmartSelectSingleFile( EFILE_TYPE_ANY,file,"scripts lua" ))
	{
		CFileUtil::EditTextFile( file );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditmodeMove() 
{
	// TODO: Add your command handler code here
	GetIEditor()->SetEditMode( eEditModeMove );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditmodeRotate() 
{
	// TODO: Add your command handler code here
	GetIEditor()->SetEditMode( eEditModeRotate );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditmodeScale() 
{
	// TODO: Add your command handler code here
	GetIEditor()->SetEditMode( eEditModeScale );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditToolLink()
{
	// TODO: Add your command handler code here
	if(GetIEditor()->GetEditTool() && GetIEditor()->GetEditTool()->IsKindOf(RUNTIME_CLASS(CLinkTool)))
		GetIEditor()->SetEditTool( 0 );
	else
		GetIEditor()->SetEditTool(new CLinkTool());
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditToolLink(CCmdUI* pCmdUI) 
{
	CEditTool *pEditTool=GetIEditor()->GetEditTool();
	if (pEditTool && (pEditTool->GetRuntimeClass()==RUNTIME_CLASS(CLinkTool)))
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditToolUnlink() 
{
	CUndo undo( "Unlink Object(s)" );
	CSelectionGroup *pSelection=GetIEditor()->GetObjectManager()->GetSelection();
	for (int i=0;i<pSelection->GetCount();i++)
	{
		CBaseObject *pBaseObj=pSelection->GetObject(i);
		pBaseObj->DetachThis();
		// It can be a special bone attachment link.
		int boneAttachLinkIndex = -1;
		if (pBaseObj->IsKindOf(RUNTIME_CLASS(CEntityObject)))
			boneAttachLinkIndex = static_cast<CEntityObject*>(pBaseObj)->GetBoneAttachLinkIndex();
		if (boneAttachLinkIndex >= 0)
		{
			static_cast<CEntityObject*>(pBaseObj)->RemoveEntityLink(boneAttachLinkIndex);
			IAnimNode *pAnimNode = static_cast<CEntityObject*>(pBaseObj)->GetAnimNode();
			if (pAnimNode && pAnimNode->IsBoneLinkTransformEnabled())
				GetIEditor()->Notify(eNotify_OnUpdateTrackView);
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditToolUnlink(CCmdUI* pCmdUI) 
{
	CSelectionGroup* pSelection = GetIEditor()->GetSelection();
	if (pSelection->IsEmpty())
		pCmdUI->Enable(FALSE);
	else if (pSelection->GetCount()==1 && !pSelection->GetObject(0)->GetParent())
	{
		bool bEntityHasBoneAttachLink = false;
		if (pSelection->GetObject(0)->IsKindOf(RUNTIME_CLASS(CEntityObject)))
			bEntityHasBoneAttachLink = static_cast<CEntityObject*>(pSelection->GetObject(0))->GetBoneAttachLinkIndex() >= 0;

		if (bEntityHasBoneAttachLink)
			pCmdUI->Enable(TRUE);
		else
			pCmdUI->Enable(FALSE);
	}
	else
		pCmdUI->Enable(TRUE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditmodeSelect() 
{
	// TODO: Add your command handler code here
	GetIEditor()->SetEditMode( eEditModeSelect );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditmodeSelectarea() 
{
	// TODO: Add your command handler code here
	GetIEditor()->SetEditMode( eEditModeSelectArea );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditmodeSelectarea(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetEditMode() == eEditModeSelectArea)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditmodeSelect(CCmdUI* pCmdUI)
{
	if (GetIEditor()->GetEditMode() == eEditModeSelect)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditmodeMove(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetEditMode() == eEditModeMove)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditmodeRotate(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetEditMode() == eEditModeRotate)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);

	CSelectionGroup* pSelection = GetIEditor()->GetSelection();
	if (pSelection->GetCount()==1 && !pSelection->GetObject(0)->IsRotatable())
		pCmdUI->Enable(FALSE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditmodeScale(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetEditMode() == eEditModeScale)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);

	CSelectionGroup* pSelection = GetIEditor()->GetSelection();
	if (pSelection->GetCount()==1 && !pSelection->GetObject(0)->IsScalable())
		pCmdUI->Enable(FALSE);
	else
	{
		for (int i=0; i<pSelection->GetCount(); ++i)
		{
			CBaseObject *pObject = pSelection->GetObject(i);
			if (pObject->IsKindOf(RUNTIME_CLASS(CEntityObject)))
			{
				CEntityObject *pEntity = static_cast<CEntityObject*>(pObject);
				if (pEntity->GetBoneAttachLinkIndex() >= 0)
				{
					pCmdUI->Enable(FALSE);
					break;
				}
			}
		}
	}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnObjectSetArea() 
{
	CSelectionGroup* pSelection = GetIEditor()->GetSelection();
	if (!pSelection->IsEmpty())
	{
		CNumberDlg dlg;
		if (dlg.DoModal() != IDOK)
			return;
	
		GetIEditor()->BeginUndo();
		float area = dlg.GetValue();
		for (int i = 0; i < pSelection->GetCount(); i++)
		{
			CBaseObject *obj = pSelection->GetObject(i);
			obj->SetArea( area );
		}
		GetIEditor()->AcceptUndo( "Set Area" );
		GetIEditor()->SetModifiedFlag();
		GetIEditor()->SetModifiedModule(eModifiedBrushes);
	}
	else
		AfxMessageBox("No objects selected");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnObjectSetHeight() 
{
	CSelectionGroup *sel = GetIEditor()->GetObjectManager()->GetSelection();
	if (!sel->IsEmpty())
	{
		float height = 0;
		if (sel->GetCount() == 1) {
			Vec3 pos = sel->GetObject(0)->GetWorldPos();
			height = pos.z - GetIEditor()->GetTerrainElevation( pos.x,pos.y );
		}
		
		CNumberDlg dlg( 0,height,"Enter Height" );
		dlg.SetRange( -10000,10000 );
		if (dlg.DoModal() != IDOK)
			return;

		CUndo undo( "Set Height" );
		height = dlg.GetValue();
		IPhysicalWorld *pPhysics = GetIEditor()->GetSystem()->GetIPhysicalWorld();
		for (int i = 0; i < sel->GetCount(); i++)
		{
			CBaseObject *obj = sel->GetObject(i);
			Matrix34 wtm = obj->GetWorldTM();
			Vec3 pos = wtm.GetTranslation();
			float z = GetIEditor()->GetTerrainElevation( pos.x,pos.y );
			if (z != pos.z)
			{
				float zdown=FLT_MAX;
				float zup=FLT_MAX;
				ray_hit hit;
				if (pPhysics->RayWorldIntersection( pos,Vec3(0,0,-4000),ent_all,rwi_stop_at_pierceable|rwi_ignore_noncolliding,&hit,1 ) > 0)
				{
					zdown = hit.pt.z;
				}
				if (pPhysics->RayWorldIntersection( pos,Vec3(0,0,4000),ent_all,rwi_stop_at_pierceable|rwi_ignore_noncolliding,&hit,1 ) > 0)
				{
					zup = hit.pt.z;
				}
				if (zdown != FLT_MAX && zup != FLT_MAX)
				{
					if (fabs(zup-z) < fabs(zdown-z))
					{
						z = zup;
					}
					else
					{
						z = zdown;
					}
				}
				else if (zup != FLT_MAX) {
					z = zup;
				}
				else if (zdown != FLT_MAX) {
					z = zdown;
				}
			}
			pos.z = z + height;
			wtm.SetTranslation(pos);
			obj->SetWorldTM( wtm );
		}
		GetIEditor()->SetModifiedFlag();
		GetIEditor()->SetModifiedModule(eModifiedBrushes);
	}
	else
		AfxMessageBox("No objects selected");
}

void CCryEditApp::OnObjectmodifyFreeze() 
{
	// Freeze selection.
	OnEditFreeze();
}

void CCryEditApp::OnObjectmodifyUnfreeze() 
{
	// Unfreeze all.
	OnEditUnfreezeall();
}

void CCryEditApp::OnViewSwitchToGame() 
{
	if (IsInPreviewMode())
		return;
	// TODO: Add your command handler code here
	bool inGame = !GetIEditor()->IsInGameMode();
	GetIEditor()->SetInGameMode( inGame );
}

void CCryEditApp::OnSelectAxisX() 
{
	if (GetIEditor()->GetAxisConstrains() != AXIS_X)
		GetIEditor()->SetAxisConstrains( AXIS_X );
	else
		GetIEditor()->SetAxisConstrains( AXIS_XY );
}

void CCryEditApp::OnSelectAxisY() 
{
	GetIEditor()->SetAxisConstrains( AXIS_Y );
}

void CCryEditApp::OnSelectAxisZ() 
{
	GetIEditor()->SetAxisConstrains( AXIS_Z );
}

void CCryEditApp::OnSelectAxisXy() 
{
	GetIEditor()->SetAxisConstrains( AXIS_XY );
}

void CCryEditApp::OnUpdateSelectAxisX(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetAxisConstrains() == AXIS_X)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

void CCryEditApp::OnUpdateSelectAxisXy(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetAxisConstrains() == AXIS_XY)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

void CCryEditApp::OnUpdateSelectAxisY(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetAxisConstrains() == AXIS_Y)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

void CCryEditApp::OnUpdateSelectAxisZ(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetAxisConstrains() == AXIS_Z)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSelectAxisTerrain() 
{
	GetIEditor()->SetAxisConstrains( AXIS_TERRAIN );
	GetIEditor()->SetTerrainAxisIgnoreObjects( true );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSelectAxisSnapToAll() 
{
	GetIEditor()->SetAxisConstrains( AXIS_TERRAIN );
	GetIEditor()->SetTerrainAxisIgnoreObjects( false );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateSelectAxisTerrain(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetAxisConstrains() == AXIS_TERRAIN && GetIEditor()->IsTerrainAxisIgnoreObjects())
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateSelectAxisSnapToAll(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetAxisConstrains() == AXIS_TERRAIN && !GetIEditor()->IsTerrainAxisIgnoreObjects())
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnExportTerrainGeom() 
{
	char szFilters[] = "Object files (*.obj)|*.obj|All files (*.*)|*.*||";
	CAutoDirectoryRestoreFileDialog dlg(FALSE, "obj", "*.obj", OFN_OVERWRITEPROMPT|OFN_NOCHANGEDIR, szFilters);

	if (dlg.DoModal() == IDOK)
	{
		BeginWaitCursor();
		AABB box;
		GetIEditor()->GetSelectedRegion(box);

		int unitSize = GetIEditor()->GetHeightmap()->GetUnitSize();
		
		// Swap x/y.
		CRect rc;
		rc.left = box.min.y / unitSize;
		rc.top = box.min.x / unitSize;
		rc.right = box.max.y / unitSize;
		rc.bottom = box.max.x / unitSize;
		GetIEditor()->GetDocument()->OnExportTerrainAsGeometrie( dlg.GetPathName(),rc );
		EndWaitCursor();
	}
}

void CCryEditApp::OnUpdateExportTerrainGeom(CCmdUI* pCmdUI) 
{
	AABB box;
	GetIEditor()->GetSelectedRegion(box);
	if (box.IsEmpty())
		pCmdUI->Enable(FALSE);
	else
		pCmdUI->Enable(TRUE);
}

void CCryEditApp::OnSelectionSave() 
{
	char szFilters[] = "Object Group Files (*.grp)|*.grp||";
	CAutoDirectoryRestoreFileDialog dlg(FALSE, "grp", NULL, OFN_OVERWRITEPROMPT|OFN_NOCHANGEDIR, szFilters);
	CFile cFile;

	if (dlg.DoModal() == IDOK) 
	{
		CWaitCursor wait;
		CSelectionGroup *sel = GetIEditor()->GetSelection();
		//CXmlArchive xmlAr( "Objects" );

		
		XmlNodeRef root = XmlHelpers::CreateXmlNode("Objects");
		CObjectArchive ar( GetIEditor()->GetObjectManager(),root,false );
		// Save all objects to XML.
		for (int i = 0; i < sel->GetCount(); i++)
		{
			ar.SaveObject( sel->GetObject(i) );
		}
		XmlHelpers::SaveXmlNode( root, dlg.GetPathName() );
		//xmlAr.Save( dlg.GetPathName() );
	}
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSelectionLoad() 
{
	// Load objects from .grp file.
	CAutoDirectoryRestoreFileDialog dlg(TRUE, "grp", "*.grp", OFN_FILEMUSTEXIST|OFN_NOCHANGEDIR, "Object Group Files (*.grp)|*.grp||");
	if (dlg.DoModal() != IDOK) 
		return;

	CWaitCursor wait;

	XmlNodeRef root = XmlHelpers::LoadXmlFromFile( dlg.GetPathName() );
	if (!root)
	{
		AfxMessageBox( "Error loading group file" );
		return;
	}

		CErrorsRecorder errorsRecorder;

	CUndo undo( "Load Objects" );

	GetIEditor()->ClearSelection();

	CObjectArchive ar( GetIEditor()->GetObjectManager(), root, true );
	GetIEditor()->GetObjectManager()->LoadObjects( ar, true );

	GetIEditor()->SetModifiedFlag();
	GetIEditor()->SetModifiedModule( eModifiedBrushes );
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGotoSelected() 
{
	CViewport *vp = GetIEditor()->GetActiveView();
	if (vp)
		vp->CenterOnSelection();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateSelected(CCmdUI* pCmdUI) 
{
	if (!GetIEditor()->GetSelection()->IsEmpty())
		pCmdUI->Enable(TRUE);
	else
		pCmdUI->Enable(FALSE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAlignObject() 
{
	// Align pick callback will release itself.
	CAlignPickCallback *alignCallback = new CAlignPickCallback;
	GetIEditor()->PickObject( alignCallback,0,"Align to Object" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAlignToGrid()
{
	if (CProceduralCreationWorks::IsProceduralCreationActivated())
	{
		CProceduralCreationWorks::ClickedGridSnap();
		return;
	}

	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (!sel->IsEmpty())
	{
		CUndo undo("Align To Grid");
		Matrix34 tm;
		for (int i = 0; i < sel->GetCount(); i++)
		{
			CBaseObject *obj = sel->GetObject(i);
			tm = obj->GetWorldTM();
			Vec3 snaped = gSettings.pGrid->Snap( tm.GetTranslation() );
			tm.SetTranslation( snaped );
			obj->SetWorldTM( tm );
			obj->OnEvent( EVENT_ALIGN_TOGRID );
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateAlignObject(CCmdUI* pCmdUI) 
{
	if (!GetIEditor()->GetSelection()->IsEmpty())
		pCmdUI->Enable(TRUE);
	else
		pCmdUI->Enable(FALSE);

	if (CAlignPickCallback::IsActive())
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAlignToVoxel() 
{
	GetIEditor()->SetEditTool(new CVoxelAligningTool());
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateAlignToVoxel(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetSelection()->GetCount()==1)
		pCmdUI->Enable(TRUE);
	else
		pCmdUI->Enable(FALSE);

	CEditTool *pEditTool=GetIEditor()->GetEditTool();
	if (pEditTool && (pEditTool->GetRuntimeClass()==RUNTIME_CLASS(CVoxelAligningTool)))
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateFreezed(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(TRUE);
}

//////////////////////////////////////////////////////////////////////////
// Groups.
//////////////////////////////////////////////////////////////////////////

void CCryEditApp::OnGroupAttach() 
{
	// TODO: Add your command handler code here
	GetIEditor()->GetSelection()->PickAndAttach();
	//GetIEditor()->SetEditTool(new CLinkTool());
}

void CCryEditApp::OnUpdateGroupAttach(CCmdUI* pCmdUI) 
{
	BOOL bEnable = FALSE;
	if (!GetIEditor()->GetSelection()->IsEmpty())
		bEnable = TRUE;
	pCmdUI->Enable( bEnable );
}

void CCryEditApp::OnGroupClose() 
{
	// Close _all_ selected open groups. 
	CSelectionGroup* selected = GetIEditor()->GetSelection();
	for( unsigned int i=0; i<selected->GetCount(); i++ )
	{
		CBaseObject *obj = selected->GetObject(i);
		if (obj && obj->GetRuntimeClass() == RUNTIME_CLASS(CGroup))
		{
			if (((CGroup*)obj)->IsOpen())
			{
				GetIEditor()->BeginUndo();
				((CGroup*)obj)->Close();
				GetIEditor()->AcceptUndo( "Group Close" );
				GetIEditor()->SetModifiedFlag();
				GetIEditor()->SetModifiedModule(eModifiedBrushes);
			}
		}
	}
}

void CCryEditApp::OnUpdateGroupClose(CCmdUI* pCmdUI) 
{
	BOOL bEnable = FALSE;

	// Alllow multiple groups to be closed at the same time.
	CSelectionGroup* selected = GetIEditor()->GetSelection();
	for( unsigned int i=0; i<selected->GetCount(); i++ )
	{
		// if there are _any_ open grouped objects selected allow them to be closed.
		CBaseObject *obj = selected->GetObject(i);
		if (obj && obj->GetRuntimeClass() == RUNTIME_CLASS(CGroup))
		{
			if (((CGroup*)obj)->IsOpen())
			{
				bEnable = TRUE;
			}
		}
	}

	pCmdUI->Enable( bEnable );
}

void CCryEditApp::OnGroupDetach() 
{
	CBaseObject *obj = GetIEditor()->GetSelectedObject();
	if (obj && obj->GetParent())
	{
		CUndo undo( "Group Detach" );
		obj->DetachThis();
	}
}


void CCryEditApp::OnShowHelpers()
{
	GetIEditor()->GetDisplaySettings()->DisplayHelpers( !GetIEditor()->GetDisplaySettings()->IsDisplayHelpers() );
	GetIEditor()->Notify(eNotify_OnDisplayRenderUpdate);
}

void CCryEditApp::OnStartStop()
{
	GetIEditor()->GetCommandManager()->Execute("FaceEditor.StartStop");
}

void CCryEditApp::OnNextKey()
{
	GetIEditor()->GetCommandManager()->Execute("FaceEditor.NextKey");
}

void CCryEditApp::OnPrevKey()
{
	GetIEditor()->GetCommandManager()->Execute("FaceEditor.PrevKey");
}

void CCryEditApp::OnNextFrame()
{
	GetIEditor()->GetCommandManager()->Execute("FaceEditor.NextFrame");
}

void CCryEditApp::OnPrevFrame()
{
	GetIEditor()->GetCommandManager()->Execute("FaceEditor.PrevFrame");
}

void CCryEditApp::OnSelectAll()
{
	GetIEditor()->GetCommandManager()->Execute("FaceEditor.SelectAll");
}

void CCryEditApp::OnKeyAll()
{
	GetIEditor()->GetCommandManager()->Execute("FaceEditor.KeyAll");
}

void CCryEditApp::OnUpdateGroupDetach(CCmdUI* pCmdUI) 
{
	BOOL bEnable = FALSE;
	CBaseObject *obj = GetIEditor()->GetSelectedObject();
	if (obj && obj->GetParent())
	{
		bEnable = TRUE;
	}
	pCmdUI->Enable( bEnable );
}

void CCryEditApp::OnGroupMake() 
{
	CStringDlg dlg( "Group Name" );

	CGroup *group = (CGroup*)GetIEditor()->NewObject( "Group" );
	if (!group)
	{
		GetIEditor()->CancelUndo();
		return;
	}

	dlg.m_strString = group->GetName();

	if (dlg.DoModal() == IDOK)
	{
		GetIEditor()->BeginUndo();

		CSelectionGroup *selection = GetIEditor()->GetSelection();
		selection->FilterParents();
		
		int i;
		std::vector<CBaseObjectPtr> objects;
		for (i = 0; i < selection->GetFilteredCount(); i++)
		{
			objects.push_back( selection->GetFilteredObject(i) );
		}
		
		// Setup a layer to the group and dont' modify the current layer (by Undo system)
		if(objects.size())
		{
			GetIEditor()->SuspendUndo();
			group->SetLayer( objects[0]->GetLayer() );
			GetIEditor()->ResumeUndo();
		}

		GetIEditor()->GetObjectManager()->ChangeObjectName( group,dlg.m_strString );

		// Snap center to grid.
		Vec3 center = gSettings.pGrid->Snap( selection->GetCenter() );
		group->SetPos( center );

		for (i = 0; i < objects.size(); i++)
		{
			GetIEditor()->GetObjectManager()->UnselectObject(objects[i]);
			group->AttachChild( objects[i] );
		}

		// need again setup the layer to inform group children
		if(objects.size())
			group->SetLayer( objects[0]->GetLayer() );

		GetIEditor()->AcceptUndo( "Group Make" );
		GetIEditor()->SetModifiedFlag();
		GetIEditor()->SetModifiedModule(eModifiedBrushes);
	}
	else
	{
		GetIEditor()->DeleteObject(group);
	}
}

void CCryEditApp::OnUpdateGroupMake(CCmdUI* pCmdUI) 
{
	OnUpdateSelected( pCmdUI );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGroupOpen() 
{
	// Ungroup all groups in selection.
	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (!sel->IsEmpty())
	{
		CUndo undo( "Group Open" );
		for (int i = 0; i < sel->GetCount(); i++)
		{
			CBaseObject *obj = sel->GetObject(i);
			if (obj && obj->GetRuntimeClass() == RUNTIME_CLASS(CGroup))
			{
				((CGroup*)obj)->Open();
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateGroupOpen(CCmdUI* pCmdUI) 
{
	BOOL bEnable = FALSE;
	CBaseObject *obj = GetIEditor()->GetSelectedObject();
	if (obj)
	{
		if (obj->GetRuntimeClass() == RUNTIME_CLASS(CGroup))
		{
			if (!((CGroup*)obj)->IsOpen())
				bEnable = TRUE;
		}
		pCmdUI->Enable( bEnable );
	}
	else
	{
		OnUpdateSelected( pCmdUI );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGroupUngroup() 
{
	// Ungroup all groups in selection.
	std::vector<CBaseObjectPtr> objects;

	CSelectionGroup *pSelection = GetIEditor()->GetSelection();
	for (int i = 0; i < pSelection->GetCount(); i++)
	{
		objects.push_back( pSelection->GetObject(i) );
	}

	if (objects.size())
	{
		CUndo undo( "Ungroup" );
		
		for (int i = 0; i < objects.size(); i++)
		{
			CBaseObject *obj = objects[i];
			if (obj && obj->GetRuntimeClass() == RUNTIME_CLASS(CGroup))
			{
				((CGroup*)obj)->Ungroup();
				GetIEditor()->DeleteObject( obj );
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateGroupUngroup(CCmdUI* pCmdUI) 
{
	CBaseObject *obj = GetIEditor()->GetSelectedObject();
	if (obj)
	{
		if (obj->GetRuntimeClass() == RUNTIME_CLASS(CGroup))
			pCmdUI->Enable( TRUE );
		else
			pCmdUI->Enable( FALSE );
	}
	else
	{
		OnUpdateSelected( pCmdUI );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnShowTips() 
{
	CTipDlg dlg;
	dlg.DoModal();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnLockSelection() 
{
	// Invert selection lock.
	GetIEditor()->LockSelection( !GetIEditor()->IsSelectionLocked() );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditLevelData() 
{
	char dir[1024];
	strcpy( dir,GetDocument()->GetPathName() );
	PathRemoveFileSpec( dir );
	CFileUtil::EditTextFile( CString(dir)+"\\LevelData.xml" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnFileEditLogFile() 
{
	CFileUtil::EditTextFile( CLogFile::GetLogFileName(),0,CFileUtil::FILE_TYPE_SCRIPT, false );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnFileEditEditorini() 
{
	CFileUtil::EditTextFile( EDITOR_INI_FILE );
}

void CCryEditApp::OnPreferences() 
{
	/*
	//////////////////////////////////////////////////////////////////////////////
	// Accels edit by CPropertyPage
	CAcceleratorManager tmpAccelManager;
	tmpAccelManager = m_AccelManager;
	CAccelMapPage page(&tmpAccelManager);
	CPropertySheet sheet;
	sheet.SetTitle( _T("Preferences") );
	sheet.AddPage(&page);
	if (sheet.DoModal() == IDOK) {
		m_AccelManager = tmpAccelManager;
		m_AccelManager.UpdateWndTable();
	}
	*/
}

void CCryEditApp::OnReloadTextures() 
{
	CWaitCursor wait;
	CLogFile::WriteLine( "Reloading Static objects textures and shaders." );
	GetIEditor()->GetObjectManager()->SendEvent( EVENT_RELOAD_TEXTURES );
	GetIEditor()->GetRenderer()->EF_ReloadTextures();
}

void CCryEditApp::OnReloadScripts() 
{
	CErrorsRecorder errRecorder;
	CWaitCursor wait;

	GetIEditor()->GetIconManager()->Reset();
	// Reload all entities and thier scripts.
	GetIEditor()->GetObjectManager()->SendEvent( EVENT_UNLOAD_ENTITY );
	// reload main.lua script.
	//GetIEditor()->GetSystem()->GetIScriptSystem()->ReloadScript( "Scripts/main.lua" );
	//GetIEditor()->GetSystem()->GetIScriptSystem()->BeginCall("Init");
	//GetIEditor()->GetSystem()->GetIScriptSystem()->EndCall();
	CEntityScriptRegistry::Instance()->Reload();
	// reload game specific (materials)
	//GetIEditor()->GetGame()->ReloadScripts();
	// Reload AI scripts.
	GetIEditor()->GetAI()->ReloadScripts();
	GetIEditor()->GetUIManager()->ReloadScripts();

	SEntityEvent event;
	event.event = ENTITY_EVENT_RELOAD_SCRIPT;
	gEnv->pEntitySystem->SendEventToAll(event);

	GetIEditor()->GetObjectManager()->SendEvent( EVENT_RELOAD_ENTITY );
}

void CCryEditApp::OnToggleMultiplayer()
{
	IEditor *pEditor = GetIEditor();
	if (pEditor->GetGameEngine()->SupportsMultiplayerGameRules())
	{
		if (pEditor->IsInGameMode())
		{
			pEditor->SetInGameMode( false );
		}

		pEditor->GetObjectManager()->SendEvent( EVENT_UNLOAD_ENTITY );

		pEditor->GetGameEngine()->ToggleMultiplayerGameRules();

		CEntityScriptRegistry::Instance()->Reload();
		pEditor->GetAI()->ReloadScripts();

		pEditor->GetObjectManager()->SendEvent( EVENT_RELOAD_ENTITY );

		CryLogAlways("Now running '%s' gamerules", pEditor->GetGame()->GetIGameFramework()->GetIGameRulesSystem()->GetCurrentGameRules()->GetEntity()->GetClass()->GetName());
	}
	else
	{
		Warning("Multiplayer gamerules not supported.");
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToggleMultiplayerUpdate( CCmdUI *pCmdUI )
{
  if (gEnv->bMultiplayer)
    pCmdUI->SetCheck(1);
  else
    pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnReloadGeometry() 
{
	CErrorsRecorder errRecorder;
	CWaitProgress wait( "Reloading static geometry" );

	CVegetationMap *vegetationMap = GetIEditor()->GetVegetationMap();
	CLogFile::WriteLine( "Reloading Static objects geometries." );
	int i;
	// Reload textures/shaders for exported static objects.
	for (i = 0; i < vegetationMap->GetObjectCount(); i++)
	{
		IStatObj *obj = vegetationMap->GetObject(i)->GetObject();
		if (obj)
		{
			obj->Refresh(FRO_SHADERS|FRO_TEXTURES|FRO_GEOMETRY);
		}
	}
	CEdMesh::ReloadAllGeometries();

  // Reload CHRs
  GetIEditor()->GetSystem()->GetIAnimationSystem()->ReloadAllModels();

	GetIEditor()->GetObjectManager()->SendEvent( EVENT_UNLOAD_GEOM );
	//GetIEditor()->Get3DEngine()->UnlockCGFResources();
	GetIEditor()->GetGame()->GetIGameFramework()->GetIItemSystem()->ClearGeometryCache();
	//GetIEditor()->Get3DEngine()->LockCGFResources();
	// Force entity system to collect garbage.
	GetIEditor()->GetSystem()->GetIEntitySystem()->Update();
	GetIEditor()->GetObjectManager()->SendEvent( EVENT_RELOAD_GEOM );
	GetIEditor()->Notify(eNotify_OnUpdateTrackView);
  
  // Rephysicalize viewport meshes
  for (int i = 0; i < GetIEditor()->GetViewManager()->GetViewCount(); ++i)
  {
  	CViewport *vp = GetIEditor()->GetViewManager()->GetView(i);
  	if (vp->IsKindOf( RUNTIME_CLASS(CModelViewport) ))
  	{
  		((CModelViewport*)vp)->RePhysicalize();
  	}
  }
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnReloadTerrain()
{
	CErrorsRecorder errRecorder;
	// Fast export.
	CGameExporter gameExporter;
	gameExporter.Export(false,true);
	// Export does it. GetIEditor()->GetGameEngine()->ReloadLevel();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUndo() 
{
	//GetIEditor()->GetObjectManager()->UndoLastOp();
	GetIEditor()->Undo();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnRedo() 
{
	GetIEditor()->Redo();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateRedo(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetUndoManager()->IsHaveRedo())
		pCmdUI->Enable(TRUE);
	else
		pCmdUI->Enable(FALSE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateUndo(CCmdUI* pCmdUI) 
{
	if (GetIEditor()->GetUndoManager()->IsHaveUndo())
		pCmdUI->Enable(TRUE);
	else
		pCmdUI->Enable(FALSE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTerrainCollision()
{
	uint32 flags = GetIEditor()->GetDisplaySettings()->GetSettings();
	if (flags&SETTINGS_NOCOLLISION)
	{
		flags &= ~SETTINGS_NOCOLLISION;
	}
	else
	{
		flags |= SETTINGS_NOCOLLISION;
	}
	GetIEditor()->GetDisplaySettings()->SetSettings(flags);
}

void CCryEditApp::OnTerrainCollisionUpdate( CCmdUI *pCmdUI )
{
	uint32 flags = GetIEditor()->GetDisplaySettings()->GetSettings();
	if (flags&SETTINGS_NOCOLLISION)
		pCmdUI->SetCheck(0);
	else
		pCmdUI->SetCheck(1);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSwitchPhysics()
{
	CWaitCursor wait;
	uint32 flags = GetIEditor()->GetDisplaySettings()->GetSettings();
	if (flags&SETTINGS_PHYSICS)
		flags &= ~SETTINGS_PHYSICS;
	else
		flags |= SETTINGS_PHYSICS;
	GetIEditor()->GetDisplaySettings()->SetSettings(flags);
	
	if ((flags&SETTINGS_PHYSICS) == 0)
	{
		GetIEditor()->GetGameEngine()->SetSimulationMode( false );
	}
	else
	{
		GetIEditor()->GetGameEngine()->SetSimulationMode( true );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSwitchPhysicsUpdate( CCmdUI *pCmdUI )
{
	if (GetIEditor()->GetGameEngine()->GetSimulationMode())
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMuteAll()
{
		ICVar* pSoundCVar = gEnv->pConsole->GetCVar( "s_SoundEnable" );
		if(pSoundCVar)
		{
				if(pSoundCVar->GetIVal() == 0)
						pSoundCVar->Set(1);
				else
						pSoundCVar->Set(0);
		}

		ICVar* pMusicCVar = gEnv->pConsole->GetCVar( "s_MusicEnable" );
		if(pMusicCVar)
		{
				if(pMusicCVar->GetIVal() == 0)
						pMusicCVar->Set(1);
				else
						pMusicCVar->Set(0);
		}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateMuteAll(CCmdUI* pCmdUI)
{
		ICVar* pSoundCVar = gEnv->pConsole->GetCVar( "s_SoundEnable" );
		if(pSoundCVar)
		{
				if(pSoundCVar->GetIVal() == 0)
						pCmdUI->SetCheck(0);
				else
						pCmdUI->SetCheck(1);
		}

		ICVar* pMusicCVar = gEnv->pConsole->GetCVar( "s_MusicEnable" );
		if(pMusicCVar)
		{
				if(pMusicCVar->GetIVal() == 0)
						pCmdUI->SetCheck(0);
				else
						pCmdUI->SetCheck(1);
		}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSyncPlayer()
{
	GetIEditor()->GetGameEngine()->SyncPlayerPosition( !GetIEditor()->GetGameEngine()->IsSyncPlayerPosition() );
}

void CCryEditApp::OnUploadFilesToConsole()
{
	static CUploadFilesToConsoleDlg dlg;

	if( !dlg.GetSafeHwnd() )
	{
		dlg.Create( CUploadFilesToConsoleDlg::IDD, AfxGetMainWnd() );
		dlg.ShowWindow( SW_SHOW );
	}
	else
	{
		dlg.ShowWindow( SW_SHOW );
	}
}

void CCryEditApp::OnForceSyncLevelFiles()
{
	std::set<CString> files;

	Log( "ForceSyncLevelFiles: Exporting to game..." );
	ExportToGame();
	Log( "ForceSyncLevelFiles: Gather asset files..." );
	CFileUtil::GatherAssetFilenamesFromLevel( files );
	Log( "ForceSyncLevelFiles: Gathered asset file count: %d", files.size() );
	Log( "ForceSyncLevelFiles: Notify file change to console..." );
	CConsoleHotUpdate::Instance().AddFiles( files );
	Log( "ForceSyncLevelFiles: Done." );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSyncPlayerUpdate( CCmdUI *pCmdUI )
{
	if (GetIEditor()->GetGameEngine()->IsSyncPlayerPosition())
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGenerateCgfThumbnails()
{
	m_pMainWnd->BeginWaitCursor();
	CThumbnailGenerator gen;
	gen.GenerateForDirectory( "Objects\\" );
	m_pMainWnd->EndWaitCursor();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIGenerateAll()
{
	CErrorsRecorder errRecorder;
	// Do game export
	CGameExporter gameExporter;
	gameExporter.Export(false,false, true);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIGenerateTriangulation()
{
	CErrorsRecorder errRecorder;
	GetIEditor()->GetGameEngine()->GenerateAiTriangulation();
	// Do game export
	CGameExporter gameExporter;
	gameExporter.Export(false,false);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIGenerateWaypoint()
{
	CErrorsRecorder errRecorder;
	GetIEditor()->GetGameEngine()->GenerateAiWaypoint();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIGenerateFlightNavigation()
{
	CErrorsRecorder errRecorder;
	GetIEditor()->GetGameEngine()->GenerateAiFlightNavigation();
	// Do game export.
	CGameExporter gameExporter;
	gameExporter.Export(false,false);
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIGenerate3dvolumes()
{
	CErrorsRecorder errRecorder;
	GetIEditor()->GetGameEngine()->GenerateAiNavVolumes();
	// Do game export.
	CGameExporter gameExporter;
	gameExporter.Export(false,false);
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIValidateNavigation()
{
	CErrorsRecorder errRecorder;
	GetIEditor()->GetGameEngine()->ValidateAINavigation();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIGenerate3DDebugVoxels()
{
	CErrorsRecorder errRecorder;
	GetIEditor()->GetGameEngine()->Generate3DDebugVoxels();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIClearAllNavigation()
{
	CErrorsRecorder errRecorder;

	GetIEditor()->GetGameEngine()->ClearAllAINavigation();

	// Do game export with empty nav data
	CGameExporter gameExporter;
	gameExporter.Export(false,false,true,false,0,false,0,true);

	GetIEditor()->GetGameEngine()->LoadAINavigationData();
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIGenerateSpawners()
{
	GenerateSpawners();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAIGenerateCoverSurfaces()
{
	CErrorsRecorder recorder;
	GetIEditor()->GetGameEngine()->GenerateAICoverSurfaces();

	// Do game export
	CGameExporter gameExporter;
	gameExporter.Export(false, false, true, GetPlatformEndian(), NULL, false, NULL, true);

	if (!GetIEditor()->GetErrorReport()->IsEmpty())
		GetIEditor()->GetErrorReport()->Display();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationDisplayAgentUpdate(CCmdUI* pCmdUI)
{
	CAIManager *pAIMgr = GetIEditor()->GetAI();
	pCmdUI->SetCheck(pAIMgr->GetNavigationDebugDisplayState());
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationShowAreas()
{
	CAIManager *pAIMgr = GetIEditor()->GetAI();
	pAIMgr->ShowNavigationAreas(!gSettings.bNavigationShowAreas);
	gSettings.bNavigationShowAreas = pAIMgr->GetShowNavigationAreasState();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationShowAreasUpdate(CCmdUI* pCmdUI)
{
	pCmdUI->SetCheck(gSettings.bNavigationShowAreas);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationEnableContinuousUpdate()
{
	if(gSettings.bIsSearchFilterActive)
	{
		CryMessageBox("You need to clear the search box before being able to re-enable Continuous Update.",
			"Warning",MB_OK);
		return;
	}
	CAIManager *pAIMgr = GetIEditor()->GetAI();
	pAIMgr->EnableNavigationContinuousUpdate(!gSettings.bNavigationContinuousUpdate);
	gSettings.bNavigationContinuousUpdate = pAIMgr->GetNavigationContinuousUpdateState();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationEnableContinuousUpdateUpdate(CCmdUI* pCmdUI)
{
	pCmdUI->SetCheck(gSettings.bNavigationContinuousUpdate);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationNewArea()
{
	OnSelectAxisSnapToAll();

	IEditor* pEditor = GetIEditor();
	pEditor->StartObjectCreation("NavigationArea");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationFullRebuild()
{
	int msgBoxResult = CryMessageBox("Are you sure you want to fully rebuild the MNM data? (The operation can take several minutes)",
		"MNM Navigation Rebuilding request",MB_YESNO|MB_ICONQUESTION);
	if(msgBoxResult == IDYES)
	{
		CAIManager *pAIMgr = GetIEditor()->GetAI();
		pAIMgr->RebuildAINavigation();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationAddSeed()
{
	IEditor* pEditor = GetIEditor();
	pEditor->StartObjectCreation("NavigationSeedPoint");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnVisualizeNavigationAccessibility()
{
	CAIManager *pAIMgr = GetIEditor()->GetAI();
	gSettings.bVisualizeNavigationAccessibility = pAIMgr->CalculateAndToggleVisualizationNavigationAccessibility();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnVisualizeNavigationAccessibilityUpdate(CCmdUI* pCmdUI)
{
	pCmdUI->SetCheck(gSettings.bVisualizeNavigationAccessibility);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAINavigationDisplayAgent()
{
	CAIManager *pAIMgr = GetIEditor()->GetAI();
	pAIMgr->EnableNavigationDebugDisplay(!gSettings.bNavigationDebugDisplay);
	gSettings.bNavigationDebugDisplay = pAIMgr->GetNavigationDebugDisplayState();
}

//////////////////////////////////////////////////////////////////////////
CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const CString& levelName, 
	int resolution, int unitSize, 
	bool bUseTerrain)
{
	CString currentLevel = GetIEditor()->GetLevelFolder();
	if ( !currentLevel.IsEmpty() )
		GetIEditor()->GetSystem()->GetIPak()->ClosePacks(currentLevel);

	CString levelPath = Path::GetGameFolder() + "/Levels/" + levelName + "/";
	CString filename = levelPath + levelName + ".cry";

	// Does the directory already exist ?
	if (PathFileExists(levelPath))
	{
		return ECLR_ALREADY_EXISTS;
	}

	CConsoleHotUpdate::Instance().CommandProcessingPause();	

	// Create the directory
	CLogFile::WriteLine("Creating level directory");
	if (!CFileUtil::CreatePath(levelPath))
	{
		return ECLR_DIR_CREATION_FAILED;
	}

	OnFileNew();
	GetIEditor()->GetDocument()->InitEmptyLevel(resolution, unitSize, bUseTerrain);

	GetIEditor()->SetStatusText("Creating Level...");

	if (bUseTerrain)
	{
		CTerrainManager::GetTerrainManager().SetTerrainSize( resolution,unitSize );
	}

	// Save the document to this folder
	GetIEditor()->GetDocument()->SetPathName(filename.GetBuffer());
	GetIEditor()->GetGameEngine()->SetLevelPath(levelPath);

	if (GetIEditor()->GetDocument()->Save())
	{
		CGameExporter gameExporter;
		gameExporter.ExportFast(true, bUseTerrain);

		GetIEditor()->GetGameEngine()->LoadLevel(levelPath, GetIEditor()->GetGameEngine()->GetMissionName(), true, true, bUseTerrain);

		GetIEditor()->GetGameEngine()->InitTerrain();

		//GetIEditor()->GetGameEngine()->LoadAINavigationData();
		if ( !bUseTerrain )
		{
			XmlNodeRef m_node = GetIEditor()->GetDocument()->GetEnvironmentTemplate();
			if ( m_node )
			{
				XmlNodeRef envState = m_node->findChild("EnvState");
				if ( envState )
				{
					XmlNodeRef showTerrainSurface = envState->findChild("ShowTerrainSurface");
					showTerrainSurface->setAttr("value", "false");
					GetIEditor()->GetGameEngine()->ReloadEnvironment();
				}
			}
		}
		else
		{
			// we need to reload environment after terrain creation in order for water to be initialized
			GetIEditor()->GetGameEngine()->ReloadEnvironment();
		}
	}

	CConsoleHotUpdate::Instance().CommandProcessingResume();

	GetIEditor()->SetStatusText("Ready");

	return ECLR_OK;
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnCreateLevel()
{
	CreateLevel();
}

//////////////////////////////////////////////////////////////////////////
bool CCryEditApp::CreateLevel()
{
	BOOL bIsDocModified = GetIEditor()->GetDocument()->IsModified();
	if (GetIEditor()->GetDocument()->IsDocumentReady() && bIsDocModified)
	{
		CString str;
		str.Format("Level %s has been changed. Save Level?", GetIEditor()->GetGameEngine()->GetLevelName());
		int result = MessageBox(AfxGetMainWnd()->GetSafeHwnd(), str, "Save Level", MB_YESNOCANCEL|MB_ICONQUESTION);
		if (IDYES == result)
		{
			GetIEditor()->GetDocument()->DoFileSave();
			bIsDocModified = FALSE;
		}
		else if (IDNO == result)
		{
			// Set Modified flag to FALSE to prevent show Save unchanged dialog again
			GetIEditor()->GetDocument()->SetModifiedFlag(FALSE);
		}
		else if (IDCANCEL == result)
		{
			return false;
		}
	}

	CNewLevelDialog dlg;

	if (dlg.DoModal() != IDOK)
	{
		GetIEditor()->GetDocument()->SetModifiedFlag(bIsDocModified);
		return false;
	}

	CString levelName = dlg.GetLevel();
	int resolution = dlg.GetTerrainResolution();
	int unitSize = dlg.GetTerrainUnits();
	bool bUseTerrain = dlg.IsUseTerrain();
	bool bGenerateTerrainTexture = dlg.IsGenerateTerrainTexture();

	ECreateLevelResult result = CreateLevel(levelName, resolution, unitSize, bUseTerrain);

	if (result == ECLR_OK && bGenerateTerrainTexture)
	{
		GenerateSurfaceTexture();
	}
	else if (result == ECLR_ALREADY_EXISTS)
	{
		AfxMessageBox( "Level with this name already exists, please choose another name.");
		return false;
	}
	else if (result == ECLR_DIR_CREATION_FAILED)
	{
		char szLevelRoot[_MAX_PATH];
		sprintf(szLevelRoot, "%s\\Levels\\%s", (const char*)Path::GetGameFolder(), (const char*)levelName );

		CString windowsErrorMessage;
		CString cwd;
		DWORD dw = GetLastError(); 

		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			dw,
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			windowsErrorMessage.GetBuffer(ERROR_LEN),
			ERROR_LEN, NULL );

		_getcwd(cwd.GetBuffer(ERROR_LEN), ERROR_LEN);

		windowsErrorMessage.ReleaseBuffer();
		cwd.ReleaseBuffer();

		CString sError;
		sError.Format("Failed to create level directory: %s\nError: %s\nCurrent Path: %s", szLevelRoot, windowsErrorMessage, cwd);
		AfxMessageBox(sError);
		return false;
	}

	return true;
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenLevel()
{
	CLevelFileDialog levelFileDialog( true );

	if ( levelFileDialog.DoModal() == IDOK )
	{
		CString levelName = levelFileDialog.GetFileName();
		m_lastOpenLevelPath = Path::GetPath(levelName);
		OpenDocumentFile(levelName);
	}
	CSWManager::Get().DeleteDoc();
}

//////////////////////////////////////////////////////////////////////////
CDocument* CCryEditApp::OpenDocumentFile(LPCTSTR lpszFileName)
{
/*
	// Create the path of the file that we are about to load 
	CString docPath = Path::GetPath(lpszFileName);
	docPath = Path::AddBackslash(docPath);

	// Check if the .cry file is in the correct folder
	if (Path::GetRelativePath(docPath).IsEmpty())
	{
		// Is this .cry file just the Hold / Fetch save ?
		if (stricmp( Path::GetFile(lpszFileName),HOLD_FETCH_FILE) != 0)
		{
			// Display user the warning
			int result = 	AfxMessageBox( _T("WARNING: You won't be able export because the .cry file is not in the Levels" \
				" folder inside the Master CD folder, or the editor executable is not in the Master CD" \
				" folder. This also prevents your from corretly using the engine preview in the 3D view." \
				" Levels must be in Levels\\ folder from the editor executable."),MB_OKCANCEL|MB_ICONWARNING );

			if (result == IDCANCEL)
				return 0;
		}
	}
*/
	CMainFrame* poFrameWindow((CMainFrame*)m_pMainWnd);

	if (poFrameWindow)
		poFrameWindow->EnableMenu(false);

	CDocument *doc = 0;
	bool bVisible=false;
	bool bTriggerConsole=false;
	if (m_pMainWnd)
	{
		doc = ((CMainFrame*)m_pMainWnd)->GetActiveDocument();
		bVisible = GetIEditor()->ShowConsole(true);
		bTriggerConsole=true;
	}

	if(GetIEditor()->GetLevelIndependentFileMan()->PromptChangedFiles())
	{
		if (doc && doc->GetPathName() == lpszFileName)
		{
			// Reloading already opened document.
			doc->GetDocTemplate()->OpenDocumentFile(doc->GetPathName());
		}
		else
		{
			doc = CWinApp::OpenDocumentFile(lpszFileName);
		}
	}
	if (bTriggerConsole)
	{
		GetIEditor()->ShowConsole(bVisible);
	}
	LoadTagLocations();

	if (poFrameWindow)
		poFrameWindow->EnableMenu(true);

	return doc;
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnLayerSelect()
{
	CPoint point;
	GetCursorPos( &point );
	CLayersSelectDialog dlg( point );
	dlg.SetSelectedLayer( GetIEditor()->GetObjectManager()->GetLayersManager()->GetCurrentLayer()->GetGUID() );
	if (dlg.DoModal() == IDOK)
	{
		CUndo undo( "Set Current Layer" );
		CObjectLayer *pLayer = GetIEditor()->GetObjectManager()->GetLayersManager()->FindLayer( dlg.GetSelectedLayer() );
		if (pLayer)
			GetIEditor()->GetObjectManager()->GetLayersManager()->SetCurrentLayer( pLayer );
	}
}
void CCryEditApp::OnRefCoordsSys()
{
	RefCoordSys coords = GetIEditor()->GetReferenceCoordSys();
	if (coords == COORDS_WORLD)
		coords = COORDS_LOCAL;
	else
		coords = COORDS_WORLD;
	GetIEditor()->SetReferenceCoordSys( coords );
}

void CCryEditApp::OnUpdateRefCoordsSys(CCmdUI *pCmdUI)
{
	RefCoordSys coords = GetIEditor()->GetReferenceCoordSys();
	if (coords == COORDS_WORLD)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnResourcesReduceworkingset()
{
	SetProcessWorkingSetSize( GetCurrentProcess(),-1,-1 );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolsGeneratelightmaps()
{
	CErrorsRecorder errRecorder;
	CLMCompDialog cDialog(m_pEditor->GetSystem());
	cDialog.DoModal();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGenLightmapsSelected()
{
	CWaitCursor cursor;
	CErrorsRecorder errRecorder;
	CLightmapGen lmGen;
	lmGen.GenerateSelected( GetIEditor() );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolsUpdatelightmaps()
{
	CWaitCursor cursor;
	CErrorsRecorder errRecorder;
	CLightmapGen lmGen;
	lmGen.GenerateChanged( GetIEditor() );
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolsEquipPacksEdit()
{
	CEquipPackDialog Dlg;
	Dlg.DoModal();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolsUpdateProcVegetation()
{
	CTerrainManager::GetTerrainManager().ReloadSurfaceTypes();

	CVegetationMap * pVegetationMap = GetIEditor()->GetVegetationMap();
	if(pVegetationMap)
		pVegetationMap->SetEngineObjectsParams();

	GetIEditor()->SetModifiedFlag();
	GetIEditor()->SetModifiedModule(eModifiedTerrain);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditHide()
{
	// Hide selection.
	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (!sel->IsEmpty())
	{
		CUndo undo( "Hide" );
		for (int i = 0; i < sel->GetCount(); i++)
		{
			GetIEditor()->GetObjectManager()->HideObject( sel->GetObject(i),true );
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditHide(CCmdUI *pCmdUI)
{
	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (!sel->IsEmpty())
		pCmdUI->Enable( TRUE );
	else
		pCmdUI->Enable( FALSE );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditUnhideall()
{
	if(MessageBox(NULL,"Are you sure you want to unhide all the objects?","Unhide All",MB_YESNO) == IDNO)
		return;
	// Unhide all.
	CUndo undo( "Unhide All" );
	GetIEditor()->GetObjectManager()->UnhideAll();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditFreeze()
{
	// Freeze selection.
	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (!sel->IsEmpty())
	{
		CUndo undo( "Freeze" );
		for (int i = 0; i < sel->GetCount(); i++)
		{
			GetIEditor()->GetObjectManager()->FreezeObject( sel->GetObject(i),true );
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateEditFreeze(CCmdUI *pCmdUI)
{
	OnUpdateEditHide( pCmdUI );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditUnfreezeall()
{
	if(MessageBox(NULL,"Are you sure you want to unfreeze all the objects?","Unfreeze All",MB_YESNO) == IDNO)
		return;
	// Unfreeze all.
	CUndo undo( "Unfreeze All" );
	GetIEditor()->GetObjectManager()->UnfreezeAll();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSnap()
{
	// Switch current snap to grid state.
	bool bGridEnabled = gSettings.pGrid->IsEnabled();
	gSettings.pGrid->Enable( !bGridEnabled );
}
	
void CCryEditApp::OnUpdateEditmodeSnap(CCmdUI* pCmdUI)
{
	bool bGridEnabled = gSettings.pGrid->IsEnabled();
	if (bGridEnabled)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

void CCryEditApp::OnWireframe()
{
	int				nWireframe(R_SOLID_MODE);
	ICVar*		r_wireframe(gEnv->pConsole->GetCVar("r_wireframe"));

	if (r_wireframe)
	{
		nWireframe=r_wireframe->GetIVal();
	}

	if (nWireframe!=R_WIREFRAME_MODE)
	{
		nWireframe=R_WIREFRAME_MODE;
	}
	else
	{
		nWireframe=R_SOLID_MODE;
	}

	if (r_wireframe)
	{
		r_wireframe->Set(nWireframe);
	}
}

void CCryEditApp::OnUpdateWireframe(CCmdUI *pCmdUI)
{
	int				nWireframe(R_SOLID_MODE);
	ICVar*		r_wireframe(gEnv->pConsole->GetCVar("r_wireframe"));

	if (r_wireframe)
	{
		nWireframe=r_wireframe->GetIVal();
	}

	if (nWireframe!=R_WIREFRAME_MODE)
	{
		pCmdUI->SetCheck(0);
	}
	else
	{
		pCmdUI->SetCheck(1);
	}
}

void CCryEditApp::OnPointmode()
{
	int				nWireframe(R_SOLID_MODE);
	ICVar*		r_wireframe(gEnv->pConsole->GetCVar("r_wireframe"));

	if (r_wireframe)
	{
		nWireframe=r_wireframe->GetIVal();
	}

	if (nWireframe!=R_POINT_MODE)
	{
		nWireframe=R_POINT_MODE;
	}
	else
	{
		nWireframe=R_SOLID_MODE;
	}

	if (r_wireframe)
	{
		r_wireframe->Set(nWireframe);
	}
}

void CCryEditApp::OnUpdatePointmode(CCmdUI *pCmdUI)
{
	int				nWireframe(R_SOLID_MODE);
	ICVar*		r_wireframe(gEnv->pConsole->GetCVar("r_wireframe"));

	if (r_wireframe)
	{
		nWireframe=r_wireframe->GetIVal();
	}

	if (nWireframe!=R_POINT_MODE)
	{
		pCmdUI->SetCheck(0);
	}
	else
	{
		pCmdUI->SetCheck(1);
	}
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnViewGridsettings()
{
	CGridSettingsDialog dlg;
	dlg.DoModal();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnViewConfigureLayout()
{
	CLayoutWnd *layout = GetIEditor()->GetViewManager()->GetLayout();
	if (layout)
	{
		CLayoutConfigDialog dlg;
		dlg.SetLayout( layout->GetLayout() );
		if (dlg.DoModal() == IDOK)
		{
			// Will kill this Pane. so must be last line in this function.
			layout->CreateLayout( dlg.GetLayout() );
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::TagLocation( int index )
{
	CViewport *pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport();
	if (!pRenderViewport)
		return;

	Vec3 vPosVec = pRenderViewport->GetViewTM().GetTranslation();

	m_tagLocations[index-1] = vPosVec;
	m_tagAngles[index-1] = Ang3::GetAnglesXYZ( Matrix33(pRenderViewport->GetViewTM()) );

	CString sTagConsoleText("");
	sTagConsoleText.Format("Camera Tag Point %d set to the position: x=%.2f, y=%.2f, z=%.2f ",index,vPosVec.x,vPosVec.y,vPosVec.z);
	GetIEditor()->WriteToConsole(sTagConsoleText);

	if (gSettings.bAutoSaveTagPoints)
		SaveTagLocations();
}

void CCryEditApp::SaveTagLocations()
{
	// Save to file.
	char filename[_MAX_PATH];
	strcpy( filename,GetIEditor()->GetDocument()->GetPathName() );
	PathRemoveFileSpec( filename );
	strcat( filename,"\\tags.txt" );
	SetFileAttributes( filename,FILE_ATTRIBUTE_NORMAL );
	FILE *f = fopen( filename,"wt" );
	if (f)
	{
		for (int i = 0; i < 12; i++)
		{
			fprintf( f,"%f,%f,%f,%f,%f,%f\n",
								m_tagLocations[i].x,m_tagLocations[i].y,m_tagLocations[i].z,
								m_tagAngles[i].x,m_tagAngles[i].y,m_tagAngles[i].z);
		}
		fclose(f);
	}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::GotoTagLocation( int index )
{
	CString sTagConsoleText("");

	if (!IsVectorsEqual(m_tagLocations[index-1],Vec3(0,0,0)))
	{
		// Change render viewport view TM to the stored one.
		CViewport *pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport();
		if (pRenderViewport)
		{
			Matrix34 tm = Matrix34::CreateRotationXYZ(  m_tagAngles[index-1] );
			tm.SetTranslation(m_tagLocations[index-1]);
			pRenderViewport->SetViewTM(tm);

			Vec3 vPosVec(tm.GetTranslation());
			sTagConsoleText.Format("Moved Camera To Tag Point %d (x=%.2f, y=%.2f, z=%.2f)",index,vPosVec.x,vPosVec.y,vPosVec.z);
		}
	}
	else
	{
		sTagConsoleText.Format("Camera Tag Point %d not set",index);
	}

	if (!sTagConsoleText.IsEmpty())
		GetIEditor()->WriteToConsole(sTagConsoleText);
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::LoadTagLocations()
{
	char filename[_MAX_PATH];
	strcpy( filename,GetIEditor()->GetDocument()->GetPathName() );
	PathRemoveFileSpec( filename );
	strcat( filename,"\\tags.txt" );
	// Load tag locations from file.

	ZeroStruct(m_tagLocations);

	FILE *f = fopen( filename,"rt" );
	if (f)
	{
		for (int i = 0; i < 12; i++)
		{
			float x=0,y=0,z=0,ax=0,ay=0,az=0;
			fscanf( f,"%f,%f,%f,%f,%f,%f\n",&x,&y,&z,&ax,&ay,&az );
			m_tagLocations[i] = Vec3(x,y,z);
			m_tagAngles[i] = Ang3(ax,ay,az);
		}
		fclose(f);
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolsLogMemoryUsage()
{
	gEnv->pConsole->ExecuteString( "SaveLevelStats" );
	//GetIEditor()->GetHeightmap()->LogLayerSizes();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTagLocation1() { TagLocation(1);}
void CCryEditApp::OnTagLocation2() { TagLocation(2);}
void CCryEditApp::OnTagLocation3() { TagLocation(3);}
void CCryEditApp::OnTagLocation4() { TagLocation(4);}
void CCryEditApp::OnTagLocation5() { TagLocation(5);}
void CCryEditApp::OnTagLocation6() { TagLocation(6);}
void CCryEditApp::OnTagLocation7() { TagLocation(7);}
void CCryEditApp::OnTagLocation8() { TagLocation(8);}
void CCryEditApp::OnTagLocation9() { TagLocation(9);}
void CCryEditApp::OnTagLocation10() { TagLocation(10);}
void CCryEditApp::OnTagLocation11() { TagLocation(11);}
void CCryEditApp::OnTagLocation12() { TagLocation(12);}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGotoLocation1() { GotoTagLocation(1);}
void CCryEditApp::OnGotoLocation2() { GotoTagLocation(2);}
void CCryEditApp::OnGotoLocation3() { GotoTagLocation(3);}
void CCryEditApp::OnGotoLocation4() { GotoTagLocation(4);}
void CCryEditApp::OnGotoLocation5() { GotoTagLocation(5);}
void CCryEditApp::OnGotoLocation6() { GotoTagLocation(6);}
void CCryEditApp::OnGotoLocation7() { GotoTagLocation(7);}
void CCryEditApp::OnGotoLocation8() { GotoTagLocation(8);}
void CCryEditApp::OnGotoLocation9() { GotoTagLocation(9);}
void CCryEditApp::OnGotoLocation10() { GotoTagLocation(10);}
void CCryEditApp::OnGotoLocation11() { GotoTagLocation(11);}
void CCryEditApp::OnGotoLocation12() { GotoTagLocation(12);}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTerrainExportblock()
{
	// TODO: Add your command handler code here
	char szFilters[] = "Terrain Block files (*.trb)|*.trb|All files (*.*)|*.*||";
	CString filename;
	if (CFileUtil::SelectSaveFile( szFilters,"trb","",filename ))
	{
		CWaitCursor wait;
		AABB box;
		GetIEditor()->GetSelectedRegion(box);

		CPoint p1 = GetIEditor()->GetHeightmap()->WorldToHmap( box.min );
		CPoint p2 = GetIEditor()->GetHeightmap()->WorldToHmap( box.max );
		CRect rect( p1,p2 );

		CXmlArchive ar("Root");
		GetIEditor()->GetHeightmap()->ExportBlock( rect,ar );

		// Save selected objects.
		CSelectionGroup *sel = GetIEditor()->GetSelection();
		XmlNodeRef objRoot = ar.root->newChild("Objects");
		CObjectArchive objAr( GetIEditor()->GetObjectManager(),objRoot,false );
		// Save all objects to XML.
		for (int i = 0; i < sel->GetCount(); i++)
		{
			CBaseObject *obj = sel->GetObject(i);
			objAr.node = objRoot->newChild( "Object" );
			obj->Serialize( objAr );
		}

		ar.Save( filename );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTerrainImportblock()
{
	// TODO: Add your command handler code here
	char szFilters[] = "Terrain Block files (*.trb)|*.trb|All files (*.*)|*.*||";
	CString filename;
	if (CFileUtil::SelectFile( szFilters,"",filename ))
	{
		CWaitCursor wait;
		CXmlArchive *ar = new CXmlArchive;
		if (!ar->Load( filename ))
		{
			MessageBox( AfxGetMainWnd()->GetSafeHwnd(),_T("Loading of Terrain Block file failed"),_T("Warning"),MB_OK|MB_ICONWARNING );
			delete ar;
			return;
		}

		CErrorsRecorder errorsRecorder;

		// Import terrain area.
		CUndo undo( "Import Terrain Area" );

		CHeightmap *pHeightmap = GetIEditor()->GetHeightmap();
		pHeightmap->ImportBlock( *ar,CPoint(0,0),false );
		// Load selection from archive.
		XmlNodeRef objRoot = ar->root->findChild("Objects");
		if (objRoot)
		{
			GetIEditor()->ClearSelection();
			CObjectArchive ar( GetIEditor()->GetObjectManager(),objRoot,true );
			GetIEditor()->GetObjectManager()->LoadObjects( ar,true );
		}

		delete ar;
		ar = 0;

		/*
		// Archive will be deleted within Move tool.
		CTerrainMoveTool *mt = new CTerrainMoveTool;
		mt->SetArchive( ar );
		GetIEditor()->SetEditTool( mt );
		*/
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateTerrainExportblock(CCmdUI *pCmdUI)
{
	AABB box;
	GetIEditor()->GetSelectedRegion(box);
	if (box.IsEmpty())
		pCmdUI->Enable(FALSE);
	else
		pCmdUI->Enable(TRUE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateTerrainImportblock(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(TRUE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnCustomizeKeyboard()
{
	((CMainFrame*)m_pMainWnd)->EditAccelerator();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnExportShortcuts()
{
	CMFCUtils::ExportShortcuts(((CMainFrame*)m_pMainWnd)->GetCommandBars()->GetShortcutManager());
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnImportShortcuts()
{
	CMFCUtils::ImportShortcuts(((CMainFrame*)m_pMainWnd)->GetCommandBars()->GetShortcutManager(), NULL);
	((CMainFrame*)m_pMainWnd)->SaveConfig();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolsConfiguretools()
{
	CXTResizePropertySheet dlg( IDS_TOOLSCONFIG,AfxGetMainWnd() );
	CToolsConfigPage page1;
	dlg.AddPage( &page1 );
	dlg.m_psh.dwFlags |= PSH_NOAPPLYNOW;
	if (dlg.DoModal() == IDOK)
	{
		//((CMainFrame*)m_pMainWnd)->UpdateToolsMenu();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnExportIndoors()
{
	//CBrushIndoor *indoor = GetIEditor()->GetObjectManager()->GetCurrentIndoor();
	//CBrushExporter exp;
	//exp.Export( indoor,"C:\\MasterCD\\Objects\\Indoor.bld" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnViewCycle2dviewport()
{
	GetIEditor()->GetViewManager()->Cycle2DViewport();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnDisplayGotoPosition()
{
	CGotoPositionDlg dlg;
	dlg.DoModal();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSnapangle()
{
	gSettings.pGrid->EnableAngleSnap( !gSettings.pGrid->IsAngleSnapEnabled() );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateSnapangle(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck( gSettings.pGrid->IsAngleSnapEnabled()?1:0 );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnRuler()
{
	CRuler *pRuler = GetIEditor()->GetRuler();
	pRuler->SetActive( !pRuler->IsActive() );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateRuler(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck( GetIEditor()->GetRuler()->IsActive()?1:0 );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnRotateselectionXaxis()
{
	CUndo undo( "Rotate X" );
	CSelectionGroup *pSelection = GetIEditor()->GetSelection();
	pSelection->Rotate( Ang3(m_fastRotateAngle,0,0),GetIEditor()->GetReferenceCoordSys() );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnRotateselectionYaxis()
{
	CUndo undo( "Rotate Y" );
	CSelectionGroup *pSelection = GetIEditor()->GetSelection();
	pSelection->Rotate( Ang3(0,m_fastRotateAngle,0),GetIEditor()->GetReferenceCoordSys() );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnRotateselectionZaxis()
{
	CUndo undo( "Rotate Z" );
	CSelectionGroup *pSelection = GetIEditor()->GetSelection();
	pSelection->Rotate( Ang3(0,0,m_fastRotateAngle),GetIEditor()->GetReferenceCoordSys() );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnRotateselectionRotateangle()
{
	CNumberDlg dlg( AfxGetMainWnd(),m_fastRotateAngle,"Rotate Angle" );
	if (dlg.DoModal() == IDOK)
	{
		m_fastRotateAngle = dlg.GetValue();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnConvertselectionTobrushes()
{
	std::vector<CBaseObjectPtr> objects;
	// Convert every possible object in selection to the brush.
	CSelectionGroup *pSelection = GetIEditor()->GetSelection();
	for (int i = 0; i < pSelection->GetCount(); i++)
	{
		objects.push_back( pSelection->GetObject(i) );
	}

	bool isFail = false;
	for (int i = 0; i < objects.size(); i++)
	{
		if(!GetIEditor()->GetObjectManager()->ConvertToType( objects[i],OBJTYPE_BRUSH ))
		{
			gEnv->pLog->LogError( "Object %s can't be converted to the brush type.", objects[i]->GetName() );
			isFail = true;
		}
	}

	if(isFail)
	{
		AfxMessageBox( "Some of the selected objects can't be converted to the brush type.", MB_ICONWARNING );
	}
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnConvertselectionTosimpleentity()
{
	std::vector<CBaseObjectPtr> objects;
	// Convert every possible object in selection to the brush.
	CSelectionGroup *pSelection = GetIEditor()->GetSelection();
	for (int i = 0; i < pSelection->GetCount(); i++)
	{
		objects.push_back( pSelection->GetObject(i) );
	}

	bool isFail = false;
	for (int i = 0; i < objects.size(); i++)
	{
		if(!GetIEditor()->GetObjectManager()->ConvertToType( objects[i],OBJTYPE_ENTITY ))
		{
			gEnv->pLog->LogError( "Object %s can't be converted to the simple entity type.", objects[i]->GetName() );
			isFail = true;
	}
}

	if(isFail)
	{
		AfxMessageBox( "Some of the selected objects can't be converted to the simple entity type.", MB_ICONWARNING );
	}
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnEditRenameobject()
{
	CSelectionGroup *pSelection = GetIEditor()->GetSelection();
	if (pSelection->IsEmpty())
	{
		AfxMessageBox( _T("No Selected Objects!") );
		return;
	}

	IObjectManager * pObjMan = GetIEditor()->GetObjectManager();

	if (!pObjMan)
		return;

	CStringDlg dlg( _T("Rename Object(s)"),AfxGetMainWnd() );
	if (dlg.DoModal() == IDOK)
	{
		CUndo undo("Rename Objects");
		CString newName;
		CString str = dlg.GetString();
		int num = 0;
		bool bWarningShown = false;

		for (int i = 0; i < pSelection->GetCount(); ++i)
		{
			CBaseObject *pObject = pSelection->GetObject(i);

			if (pObject)
			{
				if ( pObjMan->IsDuplicateObjectNameWarning(pObject,str,false) )
				{
					AfxMessageBox("There is already an object with this name.Choose a different name.");
					return;
				}
			}
		}

		for (int i = 0; i < pSelection->GetCount(); ++i)
		{
			newName.Format( "%s%d",(const char*)str,num );
			++num;
			CBaseObject *pObject = pSelection->GetObject(i);

			if (pObject)
				pObjMan->ChangeObjectName( pObject,newName );
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnChangemovespeedIncrease()
{
	gSettings.cameraMoveSpeed += m_moveSpeedStep;
	if (gSettings.cameraMoveSpeed < 0.01f)
		gSettings.cameraMoveSpeed = 0.01f;
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnChangemovespeedDecrease()
{
	gSettings.cameraMoveSpeed -= m_moveSpeedStep;
	if (gSettings.cameraMoveSpeed < 0.01f)
		gSettings.cameraMoveSpeed = 0.01f;
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnChangemovespeedChangestep()
{
	CNumberDlg dlg( AfxGetMainWnd(),m_moveSpeedStep,"Change Move Increase/Decrease Step" );
	if (dlg.DoModal() == IDOK)
	{
		m_moveSpeedStep = dlg.GetValue();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnModifyAipointPicklink()
{
	// Special command to emulate pressing pick button in ai point.
	CBaseObject *pObject = GetIEditor()->GetSelectedObject();
	if (pObject && pObject->IsKindOf(RUNTIME_CLASS(CAIPoint)))
	{
		((CAIPoint*)pObject)->StartPick();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnModifyAipointPickImpasslink()
{
	// Special command to emulate pressing pick impass button in ai point.
	CBaseObject *pObject = GetIEditor()->GetSelectedObject();
	if (pObject && pObject->IsKindOf(RUNTIME_CLASS(CAIPoint)))
	{
		((CAIPoint*)pObject)->StartPickImpass();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnPhysicsGetState()
{
	GetIEditor()->GetCommandManager()->Execute( "Physics.GetObjectsState" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnPhysicsResetState()
{
	GetIEditor()->GetCommandManager()->Execute( "Physics.ResetObjectsState" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnPhysicsSimulateObjects()
{
	GetIEditor()->GetCommandManager()->Execute( "Physics.SimulateObjects" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnFileSavelevelresources()
{
	CGameResourcesExporter saver;
	saver.GatherAllLoadedResources();
	saver.ChooseDirectoryAndSave();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnValidatelevel()
{
	// TODO: Add your command handler code here
	CLevelInfo levelInfo;
	levelInfo.Validate();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnValidateObjectPositions()
{
	IObjectManager *objMan = GetIEditor()->GetObjectManager();

	if (!objMan)
		return;

	CErrorReport errorReport;
	errorReport.SetCurrentFile("");
	errorReport.SetImmidiateMode(false);
	
	int objCount = objMan->GetObjectCount();	
	AABB bbox1;
	AABB bbox2;
	int bugNo=0;
	CString statTxt("");

	std::vector<CBaseObject*> objects;
	objMan->GetObjects(objects);

	std::vector<CBaseObject*> foundObjects;

	CVegetationMap *vegetationMap = GetIEditor()->GetVegetationMap();
	std::vector<CVegetationInstance*> foundVegetationIstances;
	std::vector<GUID> objIDs;
	bool reportVeg=false;

	for (int i1=0; i1<objCount; ++i1)
	{
		CBaseObject *pObj1= objects[i1];

		if (!pObj1)
			continue;

		// Ignore groups in search
		if (pObj1->GetType() == OBJTYPE_GROUP)
			continue;

		// Object must have geometry
		if (!pObj1->GetGeometry())
			continue;
		
		// Ignore solids
		if ( pObj1->GetType() == OBJTYPE_SOLID )
			continue;

		pObj1->GetBoundBox(bbox1);

		// Check if object has vegetation inside its bbox
		if (vegetationMap)
		{
			foundVegetationIstances.clear();
			reportVeg=false;

			vegetationMap->GetObjectInstances(bbox1.min.x,bbox1.min.y,bbox1.max.x,bbox1.max.y, foundVegetationIstances);

			for (int vegNo = 0; vegNo < foundVegetationIstances.size(); ++vegNo)
			{
				CVegetationInstance *pVegInstance=(CVegetationInstance*)foundVegetationIstances[vegNo];
				if (!pVegInstance)
					continue;

				if (!pVegInstance->object)
					continue;

				IStatObj *statObj = pVegInstance->object->GetObject();

				if (!statObj)
					continue;

				Vec3 expandMin = pVegInstance->pos + statObj->GetBoxMin() * pVegInstance->scale;
				Vec3 expandMax = pVegInstance->pos + statObj->GetBoxMax() * pVegInstance->scale;

				AABB vegBBox(expandMin,expandMax);

				if (bbox1.ContainsBox(vegBBox))
					reportVeg=true;

				if (pVegInstance->pRenderNode && reportVeg)
					pVegInstance->object->SetSelected(true);
			}

			if ( (foundVegetationIstances.size()>0) && reportVeg)
			{
				CErrorRecord error;
				error.pObject=pObj1;
				error.count=bugNo;
				error.error.Format( "%s has vegetation object(s) inside",pObj1->GetName() );
				error.description="Vegetation left inside an object";
				errorReport.ReportError(error);
			}
		}

		// Check if object has other objects inside its bbox
		foundObjects.clear();
		objMan->FindObjectsInAABB(bbox1,foundObjects);

		for (int i2=0; i2<foundObjects.size(); ++i2)
		{
			CBaseObject *pObj2= objects[i2];
			if (!pObj2)
				continue;

			if (pObj2->GetId()==pObj1->GetId())
				continue;

			if (pObj2->GetParent())
				continue;

			if ( pObj2->GetType() == OBJTYPE_SOLID )
				continue;

			if (stl::find(objIDs, pObj2->GetId() ) )
				continue;

			if ( (!pObj2->GetGeometry() || pObj2->GetType() == OBJTYPE_SOLID) && (pObj2->GetType()) )
				continue;

			pObj2->GetBoundBox(bbox2);

			if (!bbox1.IsContainPoint(bbox2.max))
				continue;

			if (!bbox1.IsContainPoint(bbox2.min))
				continue;

			objIDs.push_back(pObj2->GetId());

			CErrorRecord error;
			error.pObject=pObj2;
			error.count=bugNo;
			error.error.Format( "%s inside %s object",(const char*)pObj2->GetName(), pObj1->GetName() );
			error.description="Object left inside other object";
			errorReport.ReportError(error);
			++bugNo;
		}

		statTxt.Format("%d/%d [Reported Objects: %d]",i1,objCount,bugNo);
		GetIEditor()->SetStatusText(statTxt);
		AfxPumpMessage();
	}

	if (errorReport.GetErrorCount() == 0)
	{
		AfxMessageBox( _T("No Errors Found") );
	}
	else
		errorReport.Display();
}

void CCryEditApp::OnHelpDynamichelp()
{
	// Opens dynamic help window.
	CDynamicHelpDialog::Open();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnFileChangemod()
{
	CStringDlg dlg( "Select Current MOD",AfxGetMainWnd() );
	dlg.SetString( GetIEditor()->GetGameEngine()->GetCurrentMOD() );
	if (dlg.DoModal() == IDOK)
	{
		CString mod = dlg.GetString();
		GetIEditor()->GetGameEngine()->SetCurrentMOD( mod );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTerrainResizeterrain()
{
	if (CSWManager::Get().IsSWDoc())
	{
		CSWManager::SWMsgBox(sw::SWMsgType_Disabled);
		return;
	}

	CHeightmap *pHeightmap = GetIEditor()->GetHeightmap();

	CNewLevelDialog dlg;
	dlg.SetTerrainResolution( pHeightmap->GetWidth() );
	dlg.SetTerrainUnits( pHeightmap->GetUnitSize() );
	dlg.IsResize(true);
	if (dlg.DoModal() != IDOK)
		return;

	CUndoManager *undoMgr = GetIEditor()->GetUndoManager();
	if(undoMgr)
		undoMgr->Flush();

	int resolution = dlg.GetTerrainResolution();
	int unitSize = dlg.GetTerrainUnits();

	if (resolution != pHeightmap->GetWidth() || unitSize != pHeightmap->GetUnitSize())
	{
		pHeightmap->Resize( resolution,resolution,unitSize,false );
		UserExportToGame(true, false, false);
	}

	GetIEditor()->Notify( eNotify_OnTerrainRebuild );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolsPreferences()
{
	// Open preferences dialog.
	CPreferencesDialog dlg;
	dlg.DoModal();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnPrefabsMakeFromSelection()
{
	GetIEditor()->GetPrefabManager()->MakeFromSelection();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnPrefabsRefreshAll()
{
	GetIEditor()->GetObjectManager()->SendEvent( EVENT_PREFAB_REMAKE );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAddSelectionToPrefab()
{
	GetIEditor()->GetPrefabManager()->AddSelectionToPrefab();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolterrainmodifySmooth()
{
	GetIEditor()->GetCommandManager()->Execute( "EditTool.TerrainModifyTool.Flatten" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTerrainmodifySmooth()
{
	GetIEditor()->GetCommandManager()->Execute( "EditTool.TerrainModifyTool.Smooth" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolterrainmodifyRiseLower()
{
	GetIEditor()->GetCommandManager()->Execute( "EditTool.TerrainModifyTool.RiseLower" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnToolterrainmodifyPickHeight()
{
	GetIEditor()->GetCommandManager()->Execute( "EditTool.TerrainModifyTool.PickHeight" );
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTerrainVegetation()
{
	GetIEditor()->GetCommandManager()->Execute( "EditTool.VegetationTool.Activate" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTerrainPaintlayers()
{
	// TODO: Add your command handler code here
}

void CCryEditApp::OnAvirecorderStartavirecording()
{
	CViewport *pViewport = GetIEditor()->GetViewManager()->GetActiveViewport();
	if (pViewport)
	{
		if (m_aviFilename.IsEmpty())
		{
			if (!CFileUtil::SelectSaveFile( "AVI Files (*.avi)|*.avi","avi","",m_aviFilename ))
				return;
		}
		if (!m_aviFilename.IsEmpty())
			pViewport->StartAVIRecording( m_aviFilename );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAviRecorderStop()
{
	CViewport *pViewport = GetIEditor()->GetViewManager()->GetActiveViewport();
	if (pViewport)
	{
		pViewport->StopAVIRecording();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAviRecorderPause()
{
	CViewport *pViewport = GetIEditor()->GetViewManager()->GetActiveViewport();
	if (pViewport)
	{
		pViewport->PauseAVIRecording( !pViewport->IsAVIRecordingPaused() );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAviRecorderOutputFilename()
{
	CFileUtil::SelectSaveFile( "AVI Files (*.avi)|*.avi","avi","",m_aviFilename );
}



//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAVCRecorderStart()
{
	if (!m_pAVCompression)
	{
		return;
	}

	// Set the filename if needed
	if(!m_pAVCompression->IsFileNameSet()) 
	{
		OnAVCOutputFilename();
		if(!m_pAVCompression->IsFileNameSet()) return;
	}

	// Set the default parameters if needed
	if(!m_pAVCompression->AreParametersValid()) m_pAVCompression->SetDefaultParams();

	// Initialize the engine and start recording
	if(m_pAVCompression->InitEngine()  != AVCOMP_OK)
	{
		MessageBox( AfxGetMainWnd()->GetSafeHwnd(),_T("Could Not start Recording : Recorder Initialization Failed"),_T("Warning"),MB_OK|MB_ICONWARNING );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAVCRecorderStop()
{

	CAVCompressionReencodeDialog	oCAVCompressionReencodeDialog;

	int state = m_pAVCompression->GetState();

	// If currently transcoding, then abort it and delete files
	// If currently recording, then stop and ask what to do with the recording
	if(state == AVTHREAD_TRANSCODINGFAST || state == AVTHREAD_TRANSCODINGFULL)
	{
		m_pAVCompression->StopRecording(AVTHREAD_TRANSCODINGNULL);
	}
	else
	{

		// Ask user what they want to do with the recorded material
		int compressionMode = AVTHREAD_TRANSCODINGNULL;
		if (oCAVCompressionReencodeDialog.DoModal() == IDOK) compressionMode = oCAVCompressionReencodeDialog.getMode();
		m_pAVCompression->StopRecording(compressionMode);

		// If transcoding, create a progress bar
		if(compressionMode != AVTHREAD_TRANSCODINGNULL)
		{
			m_AVCWait = new CWaitProgress("Re-encoding the compressed data...");
		}
	}

}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAVCRecorderPause()
{
	m_pAVCompression->TogglePause();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAVCOutputFilename()
{
	CString AVCFilename;
	bool status = CFileUtil::SelectSaveFile( "AVI Files (*.avi)|*.avi","avi","",AVCFilename );
	if(status) m_pAVCompression->SetFileName(AVCFilename);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAVCSetParameters()
{

	// Set the default parameters if needed
	if(!m_pAVCompression->AreParametersValid()) m_pAVCompression->SetDefaultParams();

	AVCRecordParameters p_tmp;
	m_pAVCompression->GetParameters(&p_tmp);
	CAVCompressionDialog	oAVCompressionDialog(p_tmp.recordSize,p_tmp.recordMode,p_tmp.customWidth,p_tmp.customHeight,p_tmp.maxFileSize,p_tmp.recordTime,p_tmp.frameRate,p_tmp.recordQuality);


	if (oAVCompressionDialog.DoModal() == IDOK)
	{
		AVCRecordParameters recordParameters;
		oAVCompressionDialog.copyParms(&recordParameters);
		m_pAVCompression->SetParameters(&recordParameters);
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnAVCUpdateScreen(void)
{

	int state = m_pAVCompression->GetState();

	// If currently transcoding, update the progress bar
	if(state == AVTHREAD_TRANSCODINGFAST || state == AVTHREAD_TRANSCODINGFULL)
	{
		int percentComplete =  (int) m_pAVCompression->TranscodeProgress();
		bool status = m_AVCWait->Step( percentComplete );
		
		// Check for a cancel request
		if(status == false) m_pAVCompression->AbortTranscode();
	}
	else
	{
		// If not transcoding, then delete the progress bar if there is one since it means the transcoding has finished
		if(m_AVCWait != NULL) SAFE_DELETE(m_AVCWait);
	}

}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSwitchcameraDefaultcamera()
{
	CViewport *vp = GetIEditor()->GetViewManager()->GetSelectedViewport();
	if (vp && vp->IsKindOf(RUNTIME_CLASS(CRenderViewport)))
		((CRenderViewport*)vp)->SetDefaultCamera();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSwitchcameraSequencecamera()
{
	CViewport *vp = GetIEditor()->GetViewManager()->GetSelectedViewport();
	if (vp && vp->IsKindOf(RUNTIME_CLASS(CRenderViewport)))
		((CRenderViewport*)vp)->SetSequenceCamera();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSwitchcameraSelectedcamera()
{
	CViewport *vp = GetIEditor()->GetViewManager()->GetSelectedViewport();
	if (vp && vp->IsKindOf(RUNTIME_CLASS(CRenderViewport)))
		((CRenderViewport*)vp)->SetSelectedCamera();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSwitchcameraNext()
{
	CViewport *vp = GetIEditor()->GetActiveView();
	if (vp && vp->IsKindOf(RUNTIME_CLASS(CRenderViewport)))
		((CRenderViewport*)vp)->CycleCamera();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialAssigncurrent()
{
	GetIEditor()->ExecuteCommand( "Viewport.SetSelectedCamera" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialResettodefault()
{
	GetIEditor()->ExecuteCommand("Material.ResetSelection");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialGetmaterial()
{
	GetIEditor()->ExecuteCommand("Material.SelectFromObject");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenMaterialEditor()
{
	GetIEditor()->ExecuteCommand("Editor.Open_MaterialEditor");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenCharacterEditor()
{
	GetIEditor()->ExecuteCommand("Editor.Open_CharacterEditor");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenDataBaseView()
{
	GetIEditor()->ExecuteCommand("Editor.Open_DataBaseView");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenFlowGraphView()
{
	GetIEditor()->ExecuteCommand("Editor.Open_FlowGraph");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenAssetBrowserView()
{
	GetIEditor()->ExecuteCommand("Editor.Open_AssetBrowser");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenTrackView()
{
	GetIEditor()->ExecuteCommand("Editor.Open_TrackView");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnBrushResettransform()
{
	GetIEditor()->ExecuteCommand("Brush.ResetTransform");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnBrushMakehollow()
{
	GetIEditor()->ExecuteCommand("Brush.MakeHollow");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnBrushCsgcombine()
{
	GetIEditor()->ExecuteCommand("Brush.CSGCombine");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnBrushCsgintersect()
{
	GetIEditor()->ExecuteCommand("Brush.CSGIntersect");
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnBrushCsgsubstruct()
{
	GetIEditor()->ExecuteCommand("Brush.CSGSubstruct");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnBrushCsgsubstruct2()
{
	GetIEditor()->ExecuteCommand("Brush.CSGSubstruct2");
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnBrushCliptool()
{
	GetIEditor()->SetEditTool("EditTool.ClipBrush");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnBrushUvtool()
{
	GetIEditor()->SetEditTool("EditTool.TextureBrush");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSubobjectmodeVertex()
{
	GetIEditor()->ExecuteCommand("EditMode.SelectVertex");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSubobjectmodeEdge()
{
	GetIEditor()->ExecuteCommand("EditMode.SelectEdge");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSubobjectmodeFace()
{
	GetIEditor()->ExecuteCommand("EditMode.SelectFace");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSubobjectmodePolygon()
{
	GetIEditor()->ExecuteCommand("EditMode.SelectPolygon");
}

void CCryEditApp::OnMaterialPicktool()
{
	GetIEditor()->SetEditTool("EditTool.PickMaterial");
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnCloudsCreate() 
{
	CStringDlg dlg( "Cloud Name" );
	dlg.m_strString = GetIEditor()->GetObjectManager()->GenUniqObjectName( "Cloud" );
	if (dlg.DoModal() == IDOK)
	{
		GetIEditor()->BeginUndo();

		CCloudGroup *group = (CCloudGroup*)GetIEditor()->NewObject( "Cloud" );
		if (!group)
		{
			GetIEditor()->CancelUndo();
			return;
		}
		GetIEditor()->GetObjectManager()->ChangeObjectName( group,dlg.m_strString );

		CSelectionGroup *selection = GetIEditor()->GetSelection();
		selection->FilterParents();

		int i;
		std::vector<CBaseObjectPtr> objects;
		for (i = 0; i < selection->GetFilteredCount(); i++)
		{
			objects.push_back( selection->GetFilteredObject(i) );
		}

		// Snap center to grid.
		Vec3 center = gSettings.pGrid->Snap( selection->GetCenter() );
		group->SetPos( center );

		for (i = 0; i < objects.size(); i++)
		{
			GetIEditor()->GetObjectManager()->UnselectObject(objects[i]);
			group->AttachChild( objects[i] );
		}
		GetIEditor()->AcceptUndo( "Cloud Make" );
		GetIEditor()->SetModifiedFlag();
		GetIEditor()->SetModifiedModule(eModifiedTerrain);
		GetIEditor()->SelectObject(group);
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnCloudsDestroy() 
{
	// Ungroup all groups in selection.
	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (!sel->IsEmpty())
	{
		CUndo undo( "CloudsDestroy" );
		for (int i = 0; i < sel->GetCount(); i++)
		{
			CBaseObject *obj = sel->GetObject(i);
			if (obj && obj->GetRuntimeClass() == RUNTIME_CLASS(CCloudGroup))
			{
				((CGroup*)obj)->Ungroup();
				GetIEditor()->DeleteObject( obj );
			}
		}
	}
}


//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateCloudsDestroy(CCmdUI* pCmdUI) 
{
	CBaseObject *obj = GetIEditor()->GetSelectedObject();
	if (obj)
	{
		if (obj->GetRuntimeClass() == RUNTIME_CLASS(CCloudGroup))
			pCmdUI->Enable( TRUE );
		else
			pCmdUI->Enable( FALSE );
	}
	else
	{
		OnUpdateSelected( pCmdUI );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnCloudsOpen() 
{
	// Ungroup all groups in selection.
	CSelectionGroup *sel = GetIEditor()->GetSelection();
	if (!sel->IsEmpty())
	{
		CUndo undo( "Clouds Open" );
		for (int i = 0; i < sel->GetCount(); i++)
		{
			CBaseObject *obj = sel->GetObject(i);
			if (obj && obj->GetRuntimeClass() == RUNTIME_CLASS(CCloudGroup))
			{
				((CGroup*)obj)->Open();
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateCloudsOpen(CCmdUI* pCmdUI) 
{
	BOOL bEnable = FALSE;
	CBaseObject *obj = GetIEditor()->GetSelectedObject();
	if (obj)
	{
		if (obj->GetRuntimeClass() == RUNTIME_CLASS(CCloudGroup))
		{
			if (!((CGroup*)obj)->IsOpen())
				bEnable = TRUE;
		}
		pCmdUI->Enable( bEnable );
	}
	else
	{
		OnUpdateSelected( pCmdUI );
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnCloudsClose() 
{
	CBaseObject *obj = GetIEditor()->GetSelectedObject();
	if (obj)
	{
		GetIEditor()->BeginUndo();
		((CGroup*)obj)->Close();
		GetIEditor()->AcceptUndo( "Clouds Close" );
		GetIEditor()->SetModifiedFlag();
		GetIEditor()->SetModifiedModule(eModifiedTerrain);
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateCloudsClose(CCmdUI* pCmdUI) 
{
	BOOL bEnable = FALSE;
	CBaseObject *obj = GetIEditor()->GetSelectedObject();
	if (obj && obj->GetRuntimeClass() == RUNTIME_CLASS(CCloudGroup))
	{
		if (((CGroup*)obj)->IsOpen())
			bEnable = TRUE;
	}

	pCmdUI->Enable( bEnable );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnTimeOfDay()
{
	((CMainFrame*)m_pMainWnd)->OpenPage( "Time Of Day" );
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnResolveMissingObjects()
{
	GetIEditor()->GetObjectManager()->ResolveMissingObjects();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnClearLevelShaderList()
{
	GetIEditor()->GetDocument()->GetShaderCache()->Clear();
	GetIEditor()->SetModifiedFlag();
	GetIEditor()->SetModifiedModule(eModifiedTerrain);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenSWEditor()
{
	((CMainFrame*)m_pMainWnd)->OpenPage( "Grid Map Editor" );
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnConvertToSegmentedWorld()
{
	CSWManager::Get().ConvertToSW("");
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnSegWorldDisabled(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(FALSE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnChangeGameSpec(UINT nID)
{
	switch (nID)
	{
	case ID_GAME_ENABLELOWSPEC:
		GetIEditor()->SetEditorConfigSpec(CONFIG_LOW_SPEC);
		break;
	case ID_GAME_ENABLEMEDIUMSPEC:
		GetIEditor()->SetEditorConfigSpec(CONFIG_MEDIUM_SPEC);
		break;
	case ID_GAME_ENABLEHIGHSPEC:
		GetIEditor()->SetEditorConfigSpec(CONFIG_HIGH_SPEC);
		break;
	case ID_GAME_ENABLEVERYHIGHSPEC:
		GetIEditor()->SetEditorConfigSpec(CONFIG_VERYHIGH_SPEC);
		break;
	case ID_GAME_ENABLEX360SPEC:
		GetIEditor()->SetEditorConfigSpec(CONFIG_X360);
		break;
	case ID_GAME_ENABLEPS3SPEC:
		GetIEditor()->SetEditorConfigSpec(CONFIG_PS3);
		break;
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateGameSpec(CCmdUI *pCmdUI)
{
	int nCheck = 0;
	bool enable = true;
	switch (pCmdUI->m_nID)
	{
	case ID_GAME_ENABLELOWSPEC:
		if (GetIEditor()->GetEditorConfigSpec() == CONFIG_LOW_SPEC)
			nCheck = 1;
		enable = CONFIG_LOW_SPEC <= GetIEditor()->GetSystem()->GetMaxConfigSpec();
		break;
	case ID_GAME_ENABLEMEDIUMSPEC:
		if (GetIEditor()->GetEditorConfigSpec() == CONFIG_MEDIUM_SPEC)
			nCheck = 1;
		enable = CONFIG_MEDIUM_SPEC <= GetIEditor()->GetSystem()->GetMaxConfigSpec();
		break;
	case ID_GAME_ENABLEHIGHSPEC:
		if (GetIEditor()->GetEditorConfigSpec() == CONFIG_HIGH_SPEC)
			nCheck = 1;
		enable = CONFIG_HIGH_SPEC <= GetIEditor()->GetSystem()->GetMaxConfigSpec();
		break;
	case ID_GAME_ENABLEVERYHIGHSPEC:
		/*
#ifdef USE_WIP_FEATURES_MANAGER
		enable = IS_WIP_FEATURE_ENABLED( ID_GAME_ENABLEVERYHIGHSPEC );
		if( !IS_WIP_FEATURE_VISIBLE( ID_GAME_ENABLEVERYHIGHSPEC ) )
			return;
#endif
			*/
		if (GetIEditor()->GetEditorConfigSpec() == CONFIG_VERYHIGH_SPEC)
			nCheck = 1;
		enable = CONFIG_VERYHIGH_SPEC <= GetIEditor()->GetSystem()->GetMaxConfigSpec();
		break;
	case ID_GAME_ENABLEX360SPEC:
		if (GetIEditor()->GetEditorConfigSpec() == CONFIG_X360)
			nCheck = 1;
		enable = CONFIG_X360 <= GetIEditor()->GetSystem()->GetMaxConfigSpec();
		break;
	case ID_GAME_ENABLEPS3SPEC:
#ifdef USE_WIP_FEATURES_MANAGER
		enable = IS_WIP_FEATURE_ENABLED( ID_GAME_ENABLEPS3SPEC );
		if( !IS_WIP_FEATURE_VISIBLE( ID_GAME_ENABLEPS3SPEC ) )
			return;
#endif
		if (GetIEditor()->GetEditorConfigSpec() == CONFIG_PS3)
			nCheck = 1;
		enable = CONFIG_PS3 <= GetIEditor()->GetSystem()->GetMaxConfigSpec();
		break;
	}
	pCmdUI->SetCheck(nCheck);
	pCmdUI->Enable(enable ? TRUE : FALSE);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGameEnableSketchMode()
{
	if (gEnv && gEnv->pConsole)
	{
		// Switch sketch mode on/off.
		ICVar *e_sketch_mode = gEnv->pConsole->GetCVar("e_sketch_mode");
		if (e_sketch_mode)
		{
			if (e_sketch_mode->GetIVal() == 0)
				e_sketch_mode->Set(1);
			else
				e_sketch_mode->Set(0);
		}
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnUpdateSketchMode( CCmdUI *pCmdUI )
{
	ICVar *e_sketch_mode = 0;
	if (gEnv && gEnv->pConsole)
		e_sketch_mode = gEnv->pConsole->GetCVar("e_sketch_mode");
	if (e_sketch_mode && e_sketch_mode->GetIVal() != 0)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnGotoViewportSearch()
{
	if (m_pMainWnd && ::IsWindow(m_pMainWnd->m_hWnd) && m_pMainWnd->IsKindOf(RUNTIME_CLASS(CMainFrame)))
	{
		CLayoutViewPane* viewPane = static_cast<CLayoutViewPane*>(((CMainFrame*)m_pMainWnd)->GetActiveView());
		if (viewPane)
			viewPane->SetFocusToViewportSearch();
	}
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::AddToRecentFileList(LPCTSTR lpszPathName)
{
	// In later MFC implementations (WINVER >= 0x0601) files must exist before they can be added to the recent files list.
	// Here we override the new CWinApp::AddToRecentFileList code with the old implementation to remove this requirement.
	ASSERT_VALID(this);
	ENSURE_ARG(lpszPathName != NULL);
	ASSERT(AfxIsValidString(lpszPathName));

	if (m_pRecentFileList != NULL)
	{
		m_pRecentFileList->Add(lpszPathName);
	}

	// write the list immediately so it will be remembered even after a crash
	if(GetRecentFileList())
	GetRecentFileList()->WriteList();
	else
		CLogFile::WriteLine("ERROR: Recent File List is NULL!");
}

//////////////////////////////////////////////////////////////////////////
bool CCryEditApp::IsInRegularEditorMode()
{
	return !IsInTestMode() && !IsInPreviewMode()
		&& !IsInExportMode() && !IsInConsoleMode() && !IsInLevelLoadTestMode();
}

//////////////////////////////////////////////////////////////////////////
void CCryEditApp::FreeAssetDatabases()
{
	if (!GetIEditor())
	{
		return;
	}

	IAssetDisplayDatabase* pCurrentDatabaseInterface = NULL;
	std::vector<IClassDesc*> assetDatabasePlugins;
	IEditorClassFactory *pClassFactory = GetIEditor()->GetClassFactory();
	pClassFactory->GetClassesByCategory("Asset Display", assetDatabasePlugins);

	for(size_t i=0; i<assetDatabasePlugins.size(); ++i)
	{
		if(assetDatabasePlugins[i]->QueryInterface(__uuidof(IAssetDisplayDatabase), (void**)&pCurrentDatabaseInterface ) == S_OK)
		{
			pCurrentDatabaseInterface->FreeData();
		}
	}
}

void CCryEditApp::OnToggleRollupBar()
{
	CMainFrame *pMainFrame = (CMainFrame*)m_pMainWnd;

	if (pMainFrame)
	{
		CXTPDockingPane *pBar = pMainFrame->FindPane(_T(ROLLUP_BAR_WINDOW_TITLE));
		if (pBar)
		{
			if (pBar->IsClosed())
				pMainFrame->GetDockingPaneManager()->ShowPane(pBar);
			else
				pMainFrame->GetDockingPaneManager()->ClosePane(pBar);
		}
	}
}

void CCryEditApp::OnUpdateRollupBar(CCmdUI* pCmdUI)
{
	CMainFrame *pMainFrame = (CMainFrame*)m_pMainWnd;

	if (pMainFrame)
	{
		CXTPDockingPane *pBar = pMainFrame->FindPane(_T(ROLLUP_BAR_WINDOW_TITLE));
		if (pBar)
		{
			pCmdUI->SetCheck( (pBar->IsClosed()) ? BST_UNCHECKED : BST_CHECKED );
		}
	}
}

void CCryEditApp::OnToggleConsole()
{
	CMainFrame *pMainFrame = (CMainFrame*)m_pMainWnd;

	if (pMainFrame)
	{
		CXTPDockingPane *pBar = pMainFrame->FindPane(_T(CONSOLE_WINDOW_TITLE));
		if (pBar)
		{
			if (pBar->IsClosed())
				pMainFrame->GetDockingPaneManager()->ShowPane(pBar);
			else
				pMainFrame->GetDockingPaneManager()->ClosePane(pBar);
		}
	}
}

void CCryEditApp::OnUpdateConsole(CCmdUI* pCmdUI)
{
	CMainFrame *pMainFrame = (CMainFrame*)m_pMainWnd;

	if (pMainFrame)
	{
		CXTPDockingPane *pBar = pMainFrame->FindPane(_T(CONSOLE_WINDOW_TITLE));
		if (pBar)
		{
			pCmdUI->SetCheck( (pBar->IsClosed()) ? BST_UNCHECKED : BST_CHECKED );
		}
	}
}
